jesnault-bgp4r 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 (52) hide show
  1. data/bgp/aggregator.rb +104 -0
  2. data/bgp/as_path.rb +223 -0
  3. data/bgp/atomic_aggregate.rb +42 -0
  4. data/bgp/attribute.rb +181 -0
  5. data/bgp/attributes.rb +34 -0
  6. data/bgp/cluster_list.rb +117 -0
  7. data/bgp/common.rb +204 -0
  8. data/bgp/communities.rb +139 -0
  9. data/bgp/extended_communities.rb +107 -0
  10. data/bgp/extended_community.rb +254 -0
  11. data/bgp/iana.rb +269 -0
  12. data/bgp/io.rb +116 -0
  13. data/bgp/label.rb +94 -0
  14. data/bgp/local_pref.rb +75 -0
  15. data/bgp/message.rb +894 -0
  16. data/bgp/mp_reach.rb +208 -0
  17. data/bgp/multi_exit_disc.rb +76 -0
  18. data/bgp/neighbor.rb +291 -0
  19. data/bgp/next_hop.rb +63 -0
  20. data/bgp/nlri.rb +303 -0
  21. data/bgp/orf.rb +88 -0
  22. data/bgp/origin.rb +88 -0
  23. data/bgp/originator_id.rb +73 -0
  24. data/bgp/path_attribute.rb +210 -0
  25. data/bgp/prefix_orf.rb +263 -0
  26. data/bgp/rd.rb +107 -0
  27. data/examples/bgp +65 -0
  28. data/examples/routegen +85 -0
  29. data/examples/routegen.yml +50 -0
  30. data/test/aggregator_test.rb +66 -0
  31. data/test/as_path_test.rb +149 -0
  32. data/test/atomic_aggregate_test.rb +35 -0
  33. data/test/attribute_test.rb +57 -0
  34. data/test/cluster_list_test.rb +39 -0
  35. data/test/common_test.rb +68 -0
  36. data/test/communities_test.rb +75 -0
  37. data/test/extended_communities_test.rb +111 -0
  38. data/test/extended_community_test.rb +93 -0
  39. data/test/label_test.rb +50 -0
  40. data/test/local_pref_test.rb +43 -0
  41. data/test/message_test.rb +294 -0
  42. data/test/mp_reach_test.rb +143 -0
  43. data/test/multi_exit_disc_test.rb +46 -0
  44. data/test/neighbor_test.rb +50 -0
  45. data/test/next_hop_test.rb +37 -0
  46. data/test/nlri_test.rb +189 -0
  47. data/test/origin_test.rb +57 -0
  48. data/test/originator_id_test.rb +38 -0
  49. data/test/path_attribute_test.rb +127 -0
  50. data/test/prefix_orf_test.rb +97 -0
  51. data/test/rd_test.rb +44 -0
  52. metadata +84 -11
data/bgp/common.rb ADDED
@@ -0,0 +1,204 @@
1
+ # This file is part of BGP4R.
2
+ #
3
+ # BGP4R is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # BGP4R is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License
14
+ # along with Foobar. If not, see <http://www.gnu.org/licenses/>.
15
+
16
+ require 'ipaddr'
17
+ require 'logger'
18
+
19
+ class IPAddr
20
+ alias encode hton
21
+
22
+ def self.create(arg)
23
+ if arg.is_a?(String) and arg.is_packed?
24
+ IPAddr.new_ntoh(arg)
25
+ elsif arg.is_a?(Integer)
26
+ IPAddr.new_ntoh([arg].pack('N'))
27
+ elsif arg.is_a?(Array) and arg[0].is_a?(Fixnum)
28
+ IPAddr.new_ntoh([arg].pack('C*'))
29
+ else
30
+ IPAddr.new(arg)
31
+ end
32
+ end
33
+
34
+ #TODO: if not used, get rid of it.
35
+ def self.new_nlri4(arg)
36
+ if arg.is_a?(String) and arg.is_packed?
37
+ arg +=([0]*3).pack('C*')
38
+ plen, *nlri = arg.unpack('CC4')
39
+ ipaddr = nlri.collect { |n| n.to_s }.join('.') + "/" + plen .to_s
40
+ IPAddr.new(ipaddr)
41
+ else
42
+ IPAddr.new(arg)
43
+ end
44
+ end
45
+
46
+ def _mlen_
47
+ m = @mask_addr
48
+ len = ipv6? ? 128 : 32
49
+ loop do
50
+ break if m & 1 > 0
51
+ m = m >> 1
52
+ len += -1
53
+ end
54
+ len
55
+ end
56
+
57
+ def mlen
58
+ @_jme_mlen_ ||= _mlen_
59
+ end
60
+
61
+ def _generate_network_inc_
62
+ max_len = ipv4? ? 32 : 128
63
+ Proc.new { |n| n*(2**(max_len - mlen)) }
64
+ end
65
+ def +(i)
66
+ [IPAddr.create(to_i + i).to_s, mlen].join("/")
67
+ end
68
+ def ^(i)
69
+ @increment ||= _generate_network_inc_
70
+ [IPAddr.create(to_i + @increment.call(i)).to_s, mlen].join("/")
71
+ end
72
+ private :_generate_network_inc_
73
+
74
+ def netmask
75
+ if ipv4?
76
+ [@mask_addr].pack('N').unpack('C4').collect { |x| x.to_s}.join('.')
77
+ else
78
+ #TODO netmask ipv6
79
+ @mask_addr
80
+ end
81
+ end
82
+
83
+ end
84
+
85
+
86
+ class Object
87
+ def to_shex(*args)
88
+ self.respond_to?(:encode) ? self.encode(*args).unpack('H*')[0] : ""
89
+ end
90
+ alias to_s_hexlify to_shex
91
+ def to_shex4(*args)
92
+ self.respond_to?(:encode4) ? self.encode4(*args).unpack('H*')[0] : ""
93
+ end
94
+ def to_shex_len(len, *args)
95
+ s = to_shex(*args)
96
+ "#{s[0..len]}#{s.size>len ? '...' : ''}"
97
+ end
98
+ def to_shex4_len(len, *args)
99
+ s = to_shex4(*args)
100
+ "#{s[0..len]}#{s.size>len ? '...' : ''}"
101
+ end
102
+ end
103
+
104
+ class Array
105
+ alias_method :old_pack, :pack
106
+ def pack(*args)
107
+ s = self.old_pack(*args)
108
+ s.instance_eval { @__is_packed__ = true }
109
+ s
110
+ end
111
+ end
112
+
113
+ class String
114
+ def is_packed?
115
+ defined?(@__is_packed__) and @__is_packed__
116
+ end
117
+ def is_packed
118
+ @__is_packed__ = true
119
+ self
120
+ end
121
+ alias packed? :is_packed?
122
+
123
+ def hexlify
124
+ return self unless is_packed?
125
+ s=self.dup
126
+ ls=[""]
127
+ n=0
128
+ while s.size>0
129
+ l = s.slice!(0,16)
130
+ ls << format("0x%4.4x: %s", n,
131
+ l.unpack("n#{l.size/2}").collect { |x| format("%4.4x",x) }.join(' '))
132
+ n+=1
133
+ end
134
+ ls
135
+ end
136
+
137
+ end
138
+
139
+ class Log < Logger
140
+ private_class_method :new
141
+ @@logger = nil
142
+ def initialize(s)
143
+ super(s)
144
+ @@time=Time.now
145
+ self.datetime_format = "%M:%S"
146
+ self.level = Logger::INFO
147
+ end
148
+ def Log.time_reset
149
+ @time = Time.now
150
+ end
151
+ def Log.create(s=STDERR)
152
+ @@logger ||= new(s)
153
+ end
154
+ def Log.set_filename(s)
155
+ @@logger = new(s)
156
+ end
157
+ def Log.level=(level)
158
+ return unless (0..4) === level
159
+ @@logger.level=(level)
160
+ end
161
+ def Log.level
162
+ case @@logger.level
163
+ when Logger::INFO ; "(#{Logger::INFO }) 'INFO'"
164
+ when Logger::DEBUG ; "(#{Logger::DEBUG }) 'DEBUG'"
165
+ when Logger::WARN ; "(#{Logger::WARN }) 'WARN'"
166
+ when Logger::ERROR ; "(#{Logger::ERROR }) 'ERROR'"
167
+ when Logger::FATAL ; "(#{Logger::FATAL }) 'FATAL'"
168
+ end
169
+ end
170
+ def Log.clear
171
+ `rm #{Log.filename}`
172
+ Log.set_filename(Log.filename)
173
+ end
174
+ def Log.filename
175
+ @@logger.instance_eval { @logdev.filename }
176
+ end
177
+ def Log.start(*arg)
178
+ Log.create(*arg)
179
+ end
180
+ def Log.info(txt)
181
+ @@logger.info(txt) unless @@logger.nil?
182
+ end
183
+ def Log.fatal(txt)
184
+ @@logger.fatal(txt) unless @@logger.nil?
185
+ end
186
+ def Log.error(txt)
187
+ @@logger.error(txt) unless @@logger.nil?
188
+ end
189
+ def Log.debug(txt)
190
+ @@logger.debug(txt) unless @@logger.nil?
191
+ end
192
+ def Log.warn(txt)
193
+ @@logger.warn(txt) unless @@logger.nil?
194
+ end
195
+ def Log.<<(txt)
196
+ elapsed = Time.now - @@time
197
+ @@logger << "<< #{format "%4.6f", elapsed}: #{txt}\n" unless @@logger.nil?
198
+ end
199
+ def Log.>>(txt)
200
+ elapsed = Time.now.to_f - @@time.to_f
201
+ @@logger << ">> #{format "%4.6f", elapsed}: #{txt}\n" unless @@logger.nil?
202
+ end
203
+ end
204
+
@@ -0,0 +1,139 @@
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/attribute'
25
+
26
+
27
+ module BGP
28
+
29
+ class Communities < Attr
30
+
31
+ class Community
32
+
33
+ def initialize(arg)
34
+ if arg.is_a?(Symbol)
35
+ case arg
36
+ when :no_export ; @value=0xFFFFFF01
37
+ when :no_advertise ; @value=0xFFFFFF02
38
+ when :no_export_sub_confed ; @value=0xFFFFFF03
39
+ when :no_peer ; @value=0xFFFFFF04
40
+ else
41
+ raise ArgumentError, "invalid argument #{val}"
42
+ end
43
+ elsif arg.is_a?(String) and arg.split(':').size==2
44
+ self.value=arg.split(':').collect { |n| n.to_i }.pack('n2').unpack('N')[0]
45
+ else
46
+ self.value=arg
47
+ end
48
+ end
49
+
50
+ def value=(val)
51
+ raise ArgumentError, "invalid argument #{val}" unless val.is_a?(Fixnum) or val.is_a?(Bignum)
52
+ @value=val
53
+ end
54
+
55
+ def to_i
56
+ @value
57
+ end
58
+
59
+ def to_s
60
+ [@value >> 16, @value & 0xffff].join(':')
61
+ end
62
+
63
+ # The community attribute values ranging from 0x0000000 through
64
+ # 0x0000FFFF and 0xFFFF0000 through 0xFFFFFFFF are hereby reserved.
65
+ def is_reserved?
66
+ (0x0000000..0x0000FFFF ) === @value or (0xFFFF0000..0xFFFFFFFF) === @value
67
+ end
68
+
69
+ def encode
70
+ [@value].pack('N')
71
+ end
72
+
73
+ end
74
+
75
+ def initialize(*args)
76
+ @flags, @type = OPTIONAL_TRANSITIVE, COMMUNITIES
77
+ if args[0].is_a?(String) and args[0].is_packed?
78
+ parse(args[0])
79
+ elsif args[0].is_a?(self.class) and args[0].respond_to?(:encode)
80
+ parse(args[0].encode, *args[1..-1])
81
+ else
82
+ add(*args)
83
+ end
84
+ end
85
+
86
+ def add(*args)
87
+ @communities ||=[]
88
+ args.flatten.each do |arg|
89
+ if arg.is_a?(String) and arg.split(' ').size>1
90
+ arg.split.each { |v| @communities << Community.new(v) }
91
+ elsif arg.is_a?(String) and arg.split(',').size>1
92
+ arg.split(',').each { |v| @communities << Community.new(v) }
93
+ elsif arg.is_a?(Community)
94
+ @communities << arg
95
+ else
96
+ @communities << Community.new(arg)
97
+ end
98
+ end
99
+ end
100
+ alias << add
101
+
102
+ def communities
103
+ @communities.collect { |comm| comm.to_s }.join(' ')
104
+ end
105
+
106
+ def to_s(method=:default)
107
+ super(communities, method)
108
+ end
109
+
110
+ def to_ary
111
+ @communities.collect { |c| c.to_i }
112
+ end
113
+
114
+ def encode
115
+ super(@communities.collect { |comm| comm.encode }.join)
116
+ end
117
+
118
+ def parse(s)
119
+ @flags, @type, len, value=super(s)
120
+ self << value.unpack("N#{len/4}")
121
+ end
122
+
123
+ def sort
124
+ Communities.new(to_ary.sort)
125
+ end
126
+
127
+ def sort!
128
+ @communities = @communities.sort_by { |c| c.to_i }
129
+ self
130
+ end
131
+
132
+ def <=>(other)
133
+ self.sort.to_shex <=> other.sort.to_shex
134
+ end
135
+
136
+ end
137
+
138
+ end
139
+ load "../test/#{ File.basename($0.gsub(/.rb/,'_test.rb'))}" if __FILE__ == $0
@@ -0,0 +1,107 @@
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/attribute'
25
+ require 'bgp/extended_community'
26
+
27
+ module BGP
28
+
29
+ class Extended_communities < Attr
30
+
31
+ attr_reader :communities
32
+
33
+ def initialize(*args)
34
+ @flags, @type = OPTIONAL_TRANSITIVE, EXTENDED_COMMUNITY
35
+
36
+ if args[0].is_a?(String) and args[0].is_packed?
37
+ parse(args[0])
38
+ elsif args[0].is_a?(self.class)
39
+ parse(args[0].encode, *args[1..-1])
40
+ else
41
+ add(*args)
42
+ end
43
+ end
44
+
45
+ def add(*args)
46
+ @communities ||=[]
47
+ args.flatten.each do |arg|
48
+ if arg.is_a?(String) and arg.split(' ').size>1
49
+ arg.split.each { |v| @communities << Extended_community.factory(v) }
50
+ elsif arg.is_a?(String) and arg.split(',').size>1
51
+ arg.split(',').each { |v| @communities << Extended_community.factory(v) }
52
+ elsif arg.is_a?(Extended_community)
53
+ @communities << arg
54
+ else
55
+ @communities << Extended_community.factory(arg)
56
+ end
57
+ end
58
+ self
59
+ end
60
+ alias << add
61
+
62
+ def extended_communities
63
+ len = @communities.size*8
64
+ s=[]
65
+ s << ''
66
+ s << " Carried Extended communities"
67
+ s << " " + @communities.collect { |c| c.to_s }.join("\n ")
68
+ s.join("\n")
69
+ end
70
+
71
+ def to_s(method=:default)
72
+ super(extended_communities, method)
73
+ end
74
+
75
+ def to_arr
76
+ @communities.collect { |c| c.to_i }
77
+ end
78
+
79
+ def encode
80
+ super(@communities.collect { |comm| comm.encode }.join)
81
+ end
82
+
83
+ def parse(s)
84
+ @flags, @type, len, value=super(s)
85
+ while value.size>0
86
+ self << Extended_community.factory(value.slice!(0,8).is_packed)
87
+ end
88
+ end
89
+
90
+ def sort
91
+ Extended_communities.new(*to_arr.sort)
92
+ end
93
+
94
+ def sort!
95
+ @communities = @communities.sort_by { |c| c.to_i }
96
+ self
97
+ end
98
+
99
+ def <=>(other)
100
+ sort.to_shex <=> other.sort.to_shex
101
+ end
102
+
103
+ end
104
+
105
+ end
106
+
107
+ load "../test/#{ File.basename($0.gsub(/.rb/,'_test.rb'))}" if __FILE__ == $0
@@ -0,0 +1,254 @@
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/common'
25
+ require 'bgp/attribute'
26
+
27
+ module BGP
28
+
29
+ module ATTR::XTENDED_COMMUNITY
30
+
31
+ ROUTE_TARGET = 2
32
+ ROUTE_ORIGIN = 3
33
+ OSPF_DOMAIN_ID = 5
34
+ OSPF_ROUTER_ID = 7
35
+ BGP_DATA_COLLECT = 8
36
+
37
+ IANA_AUTHORITY_BIT = 0x8
38
+ NON_TRANSITIVE = 0x4
39
+
40
+ TWO_OCTET_AS = 0
41
+ IPV4_ADDR = 1
42
+ OPAQUE = 3
43
+
44
+ def _encoded_value_
45
+ case @type & 3
46
+ when TWO_OCTET_AS
47
+ [@global, @local].pack('nN')
48
+ when IPV4_ADDR
49
+ [@global, @local].pack('Nn')
50
+ when OPAQUE
51
+ [@global].pack('H12')
52
+ else
53
+ raise RuntimeError, "bogus type: #{@type}"
54
+ end
55
+ end
56
+
57
+ def encode
58
+ [@type, @subtype, _encoded_value_].pack('CCa6')
59
+ end
60
+
61
+ def parse(s)
62
+ @type, @subtype = s.slice!(0,2).unpack('CC')
63
+ case @type & 3
64
+ when TWO_OCTET_AS ; @global, @local = s.unpack('nN')
65
+ when IPV4_ADDR
66
+ @global, @local = s.unpack('Nn')
67
+ when OPAQUE
68
+ @global = s.unpack('H12')
69
+ end
70
+ end
71
+
72
+ def is_opaque?
73
+ @type & OPAQUE > 0
74
+ end
75
+
76
+ def is_ipv4_addr?
77
+ @type & IPV4_ADDR > 0
78
+ end
79
+
80
+ def is_two_octet_asn?
81
+ @type & 3 == TWO_OCTET_AS
82
+ end
83
+
84
+ def two_octet
85
+ @type &= ~3
86
+ end
87
+
88
+ def ipv4_addr
89
+ @type &= ~3
90
+ @type |= 1
91
+ end
92
+
93
+ def opaque
94
+ @type |= 3
95
+ end
96
+
97
+ def non_transitive
98
+ @type |= 0x40
99
+ end
100
+
101
+ def transitive
102
+ @type &= ~0x40
103
+ end
104
+
105
+ def is_transitive?
106
+ @type & 0x40 == 0
107
+ end
108
+
109
+ def non_transitive?
110
+ not is_transitive?
111
+ end
112
+
113
+ def to_i
114
+ encode.unpack('H*')[0].to_i(16)
115
+ end
116
+
117
+ def <=>(other)
118
+ to_i <=> other.to_i
119
+ end
120
+
121
+ def name
122
+ self.class.to_s.split('::').last.gsub('_',' ')
123
+ end
124
+
125
+ end
126
+
127
+
128
+ class Extended_community
129
+ include ATTR::XTENDED_COMMUNITY
130
+ include Comparable
131
+
132
+ def self.factory(_s)
133
+ if _s.is_a?(Bignum) or _s.is_a?(Fixnum)
134
+ s = [format("%16.16x",_s)].pack('H*')
135
+ else
136
+ s = _s
137
+ end
138
+ type, subtype, value = s.unpack('CCa6')
139
+ case subtype
140
+ when ROUTE_TARGET ; Route_target.new(s)
141
+ when ROUTE_ORIGIN ; Route_origin.new(s)
142
+ when OSPF_DOMAIN_ID ; Ospf_domain_id.new(s)
143
+ when OSPF_ROUTER_ID ; Ospf_router_id.new(s)
144
+ when BGP_DATA_COLLECT ; Bgp_data_collect.new(s)
145
+ else
146
+ puts "too bad type #{type}, subtype #{subtype} : #{s.unpack('H*')}"
147
+ Extended_community.new(s)
148
+ end
149
+ end
150
+
151
+ def initialize(*args)
152
+ @type=TWO_OCTET_AS
153
+ if args.size==1 and args[0].is_a?(String) and args[0].is_packed?
154
+ parse(args[0])
155
+ elsif args.size==3
156
+ @type, @subtype, value = args
157
+ raise ArgumentError, "invalid argument #{args.inspect}" unless instance_of?(Opaque)
158
+ @type |= OPAQUE
159
+ @global, @local=value, nil
160
+ elsif args.size==4
161
+ raise ArgumentError, "This is a base class and should not be instanciated" if instance_of?(Extended_community)
162
+ @type, @subtype, @global, @local = args
163
+ if @global.is_a?(String) and @local.is_a?(Fixnum)
164
+ @type |= IPV4_ADDR
165
+ @global = IPAddr.new(@global).to_i
166
+ end
167
+ elsif args.size==1 and args[0].is_a?(Bignum)
168
+ parse([s].pack('H*'))
169
+ elsif args.empty?
170
+ @type, @subtype, @global, @local = 0,0,0,0
171
+ else
172
+ raise ArgumentError, "invalid arg #{args.inspect}"
173
+ end
174
+ end
175
+
176
+ def to_s
177
+ case @type & 3
178
+ when TWO_OCTET_AS
179
+ "#{name}: #{@global}:#{@local}"
180
+ when IPV4_ADDR
181
+ "#{name}: #{IPAddr.create(@global)}:#{@local}"
182
+ when OPAQUE
183
+ "#{name}: #{@global}"
184
+ else
185
+ raise RuntimeError, "bogus type: #{@type}"
186
+ end
187
+ end
188
+
189
+ end
190
+
191
+ class Route_target < Extended_community
192
+ def initialize(*args)
193
+ if args[0].is_a?(String) and args[0].is_packed?
194
+ super(*args)
195
+ else
196
+ super(0, ROUTE_TARGET, *args)
197
+ end
198
+ end
199
+ end
200
+
201
+ class Route_origin < Extended_community
202
+ def initialize(*args)
203
+ if args[0].is_a?(String) and args[0].is_packed?
204
+ super(*args)
205
+ else
206
+ super(0,ROUTE_ORIGIN,*args)
207
+ end
208
+ end
209
+ end
210
+
211
+ class Ospf_domain_id < Extended_community
212
+ def initialize(*args)
213
+ if args[0].is_a?(String) and args[0].is_packed?
214
+ super(*args)
215
+ else
216
+ args += [0]
217
+ super(1,OSPF_DOMAIN_ID,*args)
218
+ end
219
+ end
220
+ end
221
+
222
+ class Ospf_router_id < Extended_community
223
+ def initialize(*args)
224
+ if args[0].is_a?(String) and args[0].is_packed?
225
+ super(*args)
226
+ else
227
+ args += [0]
228
+ super(1,OSPF_ROUTER_ID,*args)
229
+ end
230
+ end
231
+ end
232
+
233
+ class Bgp_data_collect < Extended_community
234
+ def initialize(*args)
235
+ if args[0].is_a?(String) and args[0].is_packed?
236
+ super(*args)
237
+ else
238
+ super(0,BGP_DATA_COLLECT,*args)
239
+ end
240
+ end
241
+ end
242
+
243
+ class Opaque < Extended_community
244
+ def initialize(*args)
245
+ if args[0].is_a?(String) and args[0].is_packed?
246
+ super(*args)
247
+ else
248
+ raise ArgumentError, "not an opaque extended community" if [2,3,5,7,8].include?(args[0])
249
+ super(0,*args)
250
+ end
251
+ end
252
+ end
253
+
254
+ end