bgp4r 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 (55) hide show
  1. data/COPYING +674 -0
  2. data/LICENSE.txt +53 -0
  3. data/README.rdoc +259 -0
  4. data/bgp/aggregator.rb +104 -0
  5. data/bgp/as_path.rb +223 -0
  6. data/bgp/atomic_aggregate.rb +42 -0
  7. data/bgp/attribute.rb +181 -0
  8. data/bgp/attributes.rb +34 -0
  9. data/bgp/cluster_list.rb +117 -0
  10. data/bgp/common.rb +204 -0
  11. data/bgp/communities.rb +139 -0
  12. data/bgp/extended_communities.rb +107 -0
  13. data/bgp/extended_community.rb +254 -0
  14. data/bgp/iana.rb +269 -0
  15. data/bgp/io.rb +116 -0
  16. data/bgp/label.rb +94 -0
  17. data/bgp/local_pref.rb +75 -0
  18. data/bgp/message.rb +894 -0
  19. data/bgp/mp_reach.rb +208 -0
  20. data/bgp/multi_exit_disc.rb +76 -0
  21. data/bgp/neighbor.rb +291 -0
  22. data/bgp/next_hop.rb +63 -0
  23. data/bgp/nlri.rb +303 -0
  24. data/bgp/orf.rb +88 -0
  25. data/bgp/origin.rb +88 -0
  26. data/bgp/originator_id.rb +73 -0
  27. data/bgp/path_attribute.rb +210 -0
  28. data/bgp/prefix_orf.rb +263 -0
  29. data/bgp/rd.rb +107 -0
  30. data/examples/bgp +65 -0
  31. data/examples/routegen +85 -0
  32. data/examples/routegen.yml +50 -0
  33. data/test/aggregator_test.rb +66 -0
  34. data/test/as_path_test.rb +149 -0
  35. data/test/atomic_aggregate_test.rb +35 -0
  36. data/test/attribute_test.rb +57 -0
  37. data/test/cluster_list_test.rb +39 -0
  38. data/test/common_test.rb +68 -0
  39. data/test/communities_test.rb +75 -0
  40. data/test/extended_communities_test.rb +111 -0
  41. data/test/extended_community_test.rb +93 -0
  42. data/test/label_test.rb +50 -0
  43. data/test/local_pref_test.rb +43 -0
  44. data/test/message_test.rb +294 -0
  45. data/test/mp_reach_test.rb +143 -0
  46. data/test/multi_exit_disc_test.rb +46 -0
  47. data/test/neighbor_test.rb +50 -0
  48. data/test/next_hop_test.rb +37 -0
  49. data/test/nlri_test.rb +189 -0
  50. data/test/origin_test.rb +57 -0
  51. data/test/originator_id_test.rb +38 -0
  52. data/test/path_attribute_test.rb +127 -0
  53. data/test/prefix_orf_test.rb +97 -0
  54. data/test/rd_test.rb +44 -0
  55. metadata +133 -0
data/LICENSE.txt ADDED
@@ -0,0 +1,53 @@
1
+ BGP4R is copyrighted free software by Jean-Michel Esnault.
2
+
3
+ You can redistribute it and/or modify it under either the terms of the GPL
4
+ (see the COPYING file), or the conditions below:
5
+
6
+ 1. You may make and give away verbatim copies of the source form of the
7
+ software without restriction, provided that you duplicate all of the
8
+ original copyright notices and associated disclaimers.
9
+
10
+ 2. You may modify your copy of the software in any way, provided that
11
+ you do at least ONE of the following:
12
+
13
+ a) place your modifications in the Public Domain or otherwise
14
+ make them Freely Available, such as by posting said
15
+ modifications to Usenet or an equivalent medium, or by allowing
16
+ the author to include your modifications in the software.
17
+
18
+ b) use the modified software only within your corporation or
19
+ organization.
20
+
21
+ c) rename any non-standard executables so the names do not conflict
22
+ with standard executables, which must also be provided.
23
+
24
+ d) make other distribution arrangements with the author.
25
+
26
+ 3. You may distribute the software in object code or executable
27
+ form, provided that you do at least ONE of the following:
28
+
29
+ a) distribute the executables and library files of the software,
30
+ together with instructions (in the manual page or equivalent)
31
+ on where to get the original distribution.
32
+
33
+ b) accompany the distribution with the machine-readable source of
34
+ the software.
35
+
36
+ c) give non-standard executables non-standard names, with
37
+ instructions on where to get the original software distribution.
38
+
39
+ d) make other distribution arrangements with the author.
40
+
41
+ 4. You may modify and include the part of the software into any other
42
+ software (possibly commercial).
43
+
44
+ 5. The scripts and library files supplied as input to or produced as
45
+ output from the software do not automatically fall under the
46
+ copyright of the software, but belong to whomever generated them,
47
+ and may be sold commercially, and may be aggregated with this
48
+ software.
49
+
50
+ 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
51
+ IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
52
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
53
+ PURPOSE.
data/README.rdoc ADDED
@@ -0,0 +1,259 @@
1
+ = BGP4R
2
+
3
+ == Description
4
+
5
+ BGP4R is a ruby library which enables the creation and manipulation of BGP messages.
6
+ In BGP4R, all well-known BGP constructs are defined in classes.
7
+
8
+ Using BGP4R, the process of building BGP messages becomes a simple matter of adding objects
9
+ to their respective containers; i.e. an attribute is added to a Path_attribute container,
10
+ while a Path_attribute object or Nlri object is added to an Update object.
11
+
12
+ = A Neighbor class is used to describe a BGP peering adjacency.
13
+
14
+
15
+ ==== A Neighbor instance can be started, stopped, and programmed to send BGP messages
16
+
17
+ Neighbor#start
18
+ Neighbor#stop
19
+ Neighbor#send_message
20
+
21
+ ==== Neighbor capabilities such as MBGP or 4-byte AS can be set using Neighbor#capability
22
+
23
+ e.g.:
24
+
25
+ neighbor = Neighbor.new \
26
+ :version=> 4,
27
+ :my_as=> 100,
28
+ :remote_addr => '192.168.1.200',
29
+ :local_addr => '192.168.1.5',
30
+ :id=> '1.1.1.1',
31
+ :holdtime=> 20
32
+
33
+ neighbor.capability :as4_byte
34
+ neighbor.capability :route_refresh
35
+ neighbor.capability :route_refresh, 128
36
+ neighbor.capability :mbgp, :ipv4, :unicast
37
+ neighbor.capability :mbgp, :ipv4, :multicast
38
+
39
+
40
+ = Ruby classes representing BGP messages, attributes, and nlri
41
+
42
+
43
+ ==== Messages:
44
+
45
+ Open
46
+ Update
47
+ Notification
48
+ Keepalive
49
+ Route_refresh
50
+
51
+ ==== Attributes:
52
+
53
+ Origin
54
+ As_path
55
+ Next_hop
56
+ Local_pref
57
+ Multi_exit_disc
58
+ Communities
59
+ Atomic_aggregate
60
+ Aggregator
61
+ Originator_id
62
+ Cluster_list
63
+ Mp_reach
64
+ Mp_unreach
65
+ As4_path
66
+ As4_aggregator
67
+ Extended_communities
68
+
69
+ ==== Update containers:
70
+
71
+ Nlri
72
+ Path_attribute
73
+ Withdrawn
74
+
75
+ = Getting started
76
+
77
+ === Here is an example illustrating how to use this API:
78
+
79
+ require 'bgp4r'
80
+ include BGP
81
+
82
+ ==== Start loggin
83
+
84
+ Log.create
85
+ Log.level=Logger::DEBUG
86
+
87
+ ==== Create a Neighbor:
88
+
89
+ neighbor = Neighbor.new \
90
+ :version=> 4,
91
+ :my_as=> 100,
92
+ :remote_addr => '192.168.1.200',
93
+ :local_addr => '192.168.1.5',
94
+ :id=> '1.1.1.1', :holdtime=> 20
95
+
96
+ ==== Set its capabilities:
97
+
98
+ neighbor.capability :as4_byte
99
+ neighbor.capability :route_refresh
100
+ neighbor.capability :route_refresh, 128
101
+ neighbor.capability :mbgp, :ipv4, :unicast
102
+ neighbor.capability :mbgp, :ipv4, :multicast
103
+
104
+
105
+ ==== Start peering:
106
+
107
+ neighbor.start :auto_retry
108
+
109
+ ==== Build an BGP Update object made up of a Path_attribute and a Nlri objects:
110
+
111
+ an_update = Update.new(
112
+ Path_attribute.new(
113
+ Origin.new(2),
114
+ Next_hop.new('192.168.1.5'),
115
+ Multi_exit_disc.new(100),
116
+ Local_pref.new(100),
117
+ As_path.new(400,300,200),
118
+ Communities.new('1311:1 311:59 2805:64')
119
+ ),
120
+ Nlri.new('77.0.0.0/17', '78.0.0.0/18', '79.0.0.0/19')
121
+ )
122
+
123
+ ==== Ship it!
124
+
125
+ neighbor.send_message an_update
126
+
127
+
128
+ === Produces:
129
+
130
+ Jean-Michel-Esnaults-MacBook-Pro-17:bgp4r jme$ ruby bgp
131
+ I, [56:08#28463] INFO -- : Open Socket old state Idle new state Active
132
+ I, [56:08#28463] INFO -- : SendOpen
133
+ D, [56:08#28463] DEBUG -- : Send Open Message (1), length: 61
134
+ Version 4, my AS 100, Holdtime 20s, ID 1.1.1.1
135
+ Capability(65): 4-octet AS number: 100
136
+ Option Capabilities Advertisement (2): [02020200]
137
+ Route Refresh (2), length: 2
138
+ Option Capabilities Advertisement (2): [02028000]
139
+ Route Refresh (Cisco) (128), length: 2
140
+ Option Capabilities Advertisement (2): [0206010400010001]
141
+ Multiprotocol Extensions (1), length: 4
142
+ AFI IPv4 (1), SAFI Unicast (1)
143
+ Option Capabilities Advertisement (2): [0206010400010002]
144
+ Multiprotocol Extensions (1), length: 4
145
+ AFI IPv4 (1), SAFI Multicast (2)
146
+
147
+ 0x0000: ffff ffff ffff ffff ffff ffff ffff ffff
148
+ 0x0001: 003d 0104 0064 0014 0101 0101 2002 0641
149
+ 0x0002: 0400 0000 6402 0202 0002 0280 0002 0601
150
+ 0x0003: 0400 0100 0102 0601 0400 0100
151
+
152
+
153
+ D, [56:08#28463] DEBUG -- : #<BGP::IO::Input:0x40ab50> #<Thread:0x40a7b8> started
154
+ D, [56:08#28463] DEBUG -- : #<BGP::IO::Output:0x40ab14> #<Thread:0x40a754> started
155
+ I, [56:08#28463] INFO -- : ev_send_open old state Active new state OpenSent
156
+ I, [56:08#28463] INFO -- : RecvOpen
157
+ D, [56:08#28463] DEBUG -- : Recv Open Message (1), length: 61
158
+ Version 4, my AS 100, Holdtime 180s, ID 2.2.2.2
159
+ Option Capabilities Advertisement (2): [0206010400010001]
160
+ Multiprotocol Extensions (1), length: 4
161
+ AFI IPv4 (1), SAFI Unicast (1)
162
+ Option Capabilities Advertisement (2): [0206010400010002]
163
+ Multiprotocol Extensions (1), length: 4
164
+ AFI IPv4 (1), SAFI Multicast (2)
165
+ Option Capabilities Advertisement (2): [02028000]
166
+ Route Refresh (Cisco) (128), length: 2
167
+ Option Capabilities Advertisement (2): [02020200]
168
+ Route Refresh (2), length: 2
169
+ Capability(65): 4-octet AS number: 100
170
+
171
+ 0x0000: ffff ffff ffff ffff ffff ffff ffff ffff
172
+ 0x0001: 003d 0104 0064 00b4 0202 0202 2002 0601
173
+ 0x0002: 0400 0100 0102 0601 0400 0100 0202 0280
174
+ 0x0003: 0002 0202 0002 0641 0400 0000
175
+
176
+
177
+ I, [56:08#28463] INFO -- : RecvOpen old state OpenSent new state OpenConfirm
178
+ I, [56:08#28463] INFO -- : RecvKeepalive
179
+ D, [56:08#28463] DEBUG -- : Recv Keepalive Message (4), length: 19, [001304]
180
+
181
+ I, [56:08#28463] INFO -- : SendKeepalive
182
+ D, [56:08#28463] DEBUG -- : Send Keepalive Message (4), length: 19, [001304]
183
+
184
+ D, [56:08#28463] DEBUG -- : SendKeepAlive
185
+ I, [56:08#28463] INFO -- : RecvKeepAlive old state OpenConfirm new state Established
186
+ I, [56:08#28463] INFO -- : RecvKeepalive
187
+ D, [56:08#28463] DEBUG -- : Recv Keepalive Message (4), length: 19, [001304]
188
+
189
+ I, [56:08#28463] INFO -- : version: 4, id: 1.1.1.1, as: 100, holdtime: 20, peer addr: 192.168.1.200, local addr: 192.168.1.5 started
190
+ I, [56:08#28463] INFO -- : SendUpdate
191
+ D, [56:08#28463] DEBUG -- : Send Update Message (2), 4 bytes AS, length: 92
192
+ Path Attributes:
193
+ Origin (1), length: 1, Flags [T]: incomplete
194
+ 0x0000:
195
+ Next Hop (3), length: 4, Flags [T]: 192.168.1.5
196
+ 0x0000: c0a8 0105
197
+ Multi Exit Disc (4), length: 4, Flags [O]: (0x0064) 100
198
+ 0x0000: 0000 0064
199
+ Local Pref (5), length: 4, Flags [T]: (0x0064) 100
200
+ 0x0000: 0000 0064
201
+ As Path (2), length: 14, Flags [T]: 400 300 200
202
+ 0x0000: 0203 0000 0190 0000 012c 0000 00c8
203
+ Communities (8), length: 12, Flags [OT]: 1311:1 311:59 2805:64
204
+ 0x0000: 051f 0001 0137 003b 0af5 0040
205
+ 77.0.0.0/17
206
+ 78.0.0.0/18
207
+ 79.0.0.0/19
208
+
209
+ 0x0000: ffff ffff ffff ffff ffff ffff ffff ffff
210
+ 0x0001: 005c 0200 0000 3940 0101 0240 0304 c0a8
211
+ 0x0002: 0105 8004 0400 0000 6440 0504 0000 0064
212
+ 0x0003: 4002 0e02 0300 0001 9000 0001 2c00 0000
213
+ 0x0004: c8c0 080c 051f 0001 0137 003b 0af5 0040
214
+ 0x0005: 114d 0000 124e 0000 134f 0000
215
+
216
+
217
+ I, [56:13#28463] INFO -- : RecvKeepalive
218
+ D, [56:13#28463] DEBUG -- : Recv Keepalive Message (4), length: 19, [001304]
219
+
220
+ I, [56:14#28463] INFO -- : SendKeepalive
221
+ D, [56:14#28463] DEBUG -- : Send Keepalive Message (4), length: 19, [001304]
222
+
223
+
224
+ == Source Code
225
+
226
+ Source code is hosted on github.
227
+
228
+ == Installation
229
+
230
+ ==== Run the following if you haven't already:
231
+
232
+ gem sources -a http://gems.github.com
233
+
234
+ ==== Install the gem
235
+
236
+ sudo gem install jesnault-bgp4r
237
+
238
+ === Or clone bgp4r tree and set RUBYLIB env variable accordingly:
239
+
240
+ git clone git://github.com/jesnault/bgp4r.git
241
+ export RUBYLIB=/home/user/bgp4r
242
+
243
+ == Requirements
244
+
245
+
246
+ == License
247
+
248
+ BGP4R is free software: you can redistribute it and/or modify
249
+ it under the terms of the GNU General Public License as published by
250
+ the Free Software Foundation, either version 3 of the License, or
251
+ (at your option) any later version.
252
+
253
+ BGP4R is distributed in the hope that it will be useful,
254
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
255
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
256
+ GNU General Public License for more details.
257
+
258
+ You should have received a copy of the GNU General Public License
259
+ along with BGP4R. If not, see <http://www.gnu.org/licenses/>.
data/bgp/aggregator.rb ADDED
@@ -0,0 +1,104 @@
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/attribute'
24
+
25
+ module BGP
26
+
27
+ class Aggregator < Attr
28
+
29
+ def initialize(*args)
30
+ @flags, @type, @as4byte =OPTIONAL_TRANSITIVE, AGGREGATOR, false
31
+ if args[0].is_a?(String) and args[0].is_packed?
32
+ parse(*args)
33
+ elsif args.size==2 and
34
+ args[0].is_a?(String) and (args[1].is_a?(Fixnum) or args[1].is_a?(Bignum))
35
+ @ip_address = IPAddr.create(args[0])
36
+ @as = args[1]
37
+ elsif args[0].is_a?(self.class)
38
+ parse(args[0].encode, *args[1..-1])
39
+ else
40
+ raise ArgumentError, "invalid argument, #{args.inspect}"
41
+ end
42
+ end
43
+
44
+ def address=(val)
45
+ @ip_address=IPAddr.create(val)
46
+ end
47
+
48
+ def address
49
+ @ip_address.to_s
50
+ end
51
+
52
+ def as(sep='')
53
+ case sep
54
+ when '.'
55
+ has = @as >> 16
56
+ las = @as & 0xffff
57
+ [has,las].join('.')
58
+ else
59
+ @as
60
+ end
61
+ end
62
+
63
+ def aggregator(as4byte=@as4byte)
64
+ "#{address}, #{as(as4byte ? '.':'')}"
65
+ end
66
+
67
+ def to_s(method=:default)
68
+ super(aggregator, method)
69
+ end
70
+
71
+ def parse(s,as4byte=false)
72
+ @flags, @type, len, @as, addr = super(s, as4byte ? 'NN' : 'nN')
73
+ self.address = addr
74
+ end
75
+
76
+ def encode(as4byte=@as4byte)
77
+ f = as4byte ? 'N' : 'n'
78
+ super([@as].pack(f) + @ip_address.hton)
79
+ end
80
+
81
+ end
82
+
83
+ class As4_aggregator < Aggregator
84
+ def initialize(*args)
85
+ super(*args)
86
+ @flags, @type, @as4byte =OPTIONAL_TRANSITIVE, AS4_AGGREGATOR, true
87
+ end
88
+ def parse(s,as4byte=@as4byte)
89
+ super(s,true)
90
+ end
91
+ def encode(as4byte=@as4byte)
92
+ f = as4byte ? 'N' : 'n'
93
+ super([@as].pack(f) + @ip_address.hton)
94
+ end
95
+
96
+ def aggregator(as4byte=@as4byte)
97
+ super(true)
98
+ end
99
+
100
+ end
101
+
102
+ end
103
+
104
+ load "../test/#{ File.basename($0.gsub(/.rb/,'_test.rb'))}" if __FILE__ == $0
data/bgp/as_path.rb ADDED
@@ -0,0 +1,223 @@
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/attribute'
24
+
25
+ module BGP
26
+
27
+ class As_path < Attr
28
+
29
+ ##############################
30
+
31
+ class Segment
32
+ include ATTR
33
+
34
+ def self.factory(s, as4byte=false)
35
+ seg_type, num = s.slice(0,2).unpack('CC')
36
+ len = num * (as4byte ? 4 : 2)+2
37
+ segment = s.slice!(0, len).is_packed
38
+ case seg_type
39
+ when SET ; Set.new(segment, as4byte)
40
+ when SEQUENCE ; Sequence.new(segment, as4byte)
41
+ when CONFED_SEQUENCE ; Confed_sequence.new(segment, as4byte)
42
+ when CONFED_SET ; Confed_set.new(segment, as4byte)
43
+ end
44
+ end
45
+
46
+ attr_reader :as
47
+
48
+ def initialize(seg_type, *args)
49
+ @as=[]
50
+ if seg_type.is_a?(String) and seg_type.is_packed?
51
+ parse(seg_type, *args)
52
+ elsif args.size>0 and args.is_a?(Array)
53
+ self.seg_type = seg_type
54
+ @as = args
55
+ else
56
+ raise ArgumentError, "invalid argument #{args.inspect}"
57
+ end
58
+
59
+ end
60
+
61
+ def seg_type
62
+ @seg_type
63
+ end
64
+
65
+ def seg_type=(val)
66
+ case val
67
+ when :set ; @seg_type = SET
68
+ when :sequence ; @seg_type = SEQUENCE
69
+ when :confed_sequence ; @seg_type = CONFED_SEQUENCE
70
+ when :confed_set ; @seg_type = CONFED_SET
71
+ else
72
+ raise ArgumentError, "invalid segment type #{val.class} #{val}"
73
+ end
74
+ end
75
+
76
+ def encode(as4byte=false)
77
+ [@seg_type, @as.size, @as].flatten.pack("CC#{as4byte ? 'N' : 'n'}*")
78
+ end
79
+
80
+ def as4byte?
81
+ defined?(@as4byte) and @as4byte
82
+ end
83
+
84
+ def parse(s, as4byte=false)
85
+ @seg_type, skip, *@as = s.unpack("CC#{as4byte ? 'N' : 'n'}*")
86
+ @as = [@as].flatten
87
+ end
88
+
89
+ def to_s
90
+ case @seg_type
91
+ when SET ; s = "{" ; join=", "
92
+ when SEQUENCE ; s = "" ; join= " "
93
+ when CONFED_SET ; s = "[" ; join= ", "
94
+ when CONFED_SEQUENCE ; s = "(" ; join= " "
95
+ else ; s = "?("
96
+ end
97
+ s += @as.join(join)
98
+ case @seg_type
99
+ when SET ; s += "}"
100
+ when CONFED_SET ; s += "]"
101
+ when CONFED_SEQUENCE ; s += ")"
102
+ when SEQUENCE
103
+ else ; s += ")"
104
+ end
105
+ s
106
+ end
107
+
108
+ end
109
+
110
+ class As_path::Set < As_path::Segment
111
+ def initialize(*args)
112
+ if args[0].is_a?(String)
113
+ super(*args)
114
+ else
115
+ super(:set, *args)
116
+ end
117
+ end
118
+ end
119
+
120
+ class As_path::Sequence < As_path::Segment
121
+ def initialize(*args)
122
+ if args[0].is_a?(String)
123
+ super(*args)
124
+ else
125
+ super(:sequence, *args)
126
+ end
127
+ end
128
+ end
129
+
130
+ class As_path::Confed_set < As_path::Segment
131
+ def initialize(*args)
132
+ if args[0].is_a?(String)
133
+ super(*args)
134
+ else
135
+ super(:confed_set, *args)
136
+ end
137
+ end
138
+ end
139
+
140
+ class As_path::Confed_sequence < As_path::Segment
141
+ def initialize(*args)
142
+ if args[0].is_a?(String)
143
+ super(*args)
144
+ else
145
+ super(:confed_sequence, *args)
146
+ end
147
+ end
148
+ end
149
+
150
+ ##############################
151
+
152
+ def integer?(arg)
153
+ arg.is_a?(Fixnum) or arg.is_a?(Bignum)
154
+ end
155
+
156
+ attr_accessor :as4byte
157
+
158
+ def initialize(*args)
159
+
160
+ @flags, @type, @segments, @as4byte = WELL_KNOWN_MANDATORY, AS_PATH, [], false
161
+
162
+ if args[0].is_a?(String) and args[0].is_packed?
163
+ parse(*args)
164
+ elsif args[0].is_a?(self.class)
165
+ parse(args[0].encode, *args[1..-1])
166
+ elsif integer?(args[0])
167
+ @segments << Sequence.new(*args.dup)
168
+ elsif args[0].is_a?(Segment)
169
+ unless args.find { |seg| ! seg.is_a?(Segment) }.nil?
170
+ raise ArgumentError, "at least one arg is not a segment"
171
+ end
172
+ @segments = args.dup
173
+ end
174
+
175
+ end
176
+
177
+ def <<(val)
178
+ raise ArgumentError, "invalid argument, #{val.class} #{val}" unless val.is_a?(Segment)
179
+ @segments << val
180
+ end
181
+
182
+ def encode(as4byte=@as4byte)
183
+ super(@segments.collect { |segment| segment.encode(as4byte) }.join)
184
+ end
185
+
186
+ def encode4
187
+ encode(true)
188
+ end
189
+
190
+ def as_path
191
+ return 'empty' if @segments.empty?
192
+ @segments.collect { |seg| seg.to_s }.join(' ')
193
+ end
194
+
195
+ def to_s(method=:default, as4byte=false)
196
+ super(as_path, method, as4byte)
197
+ end
198
+
199
+ private
200
+
201
+ def parse(s,as4byte=false)
202
+ @flags, @type, len, value=super(s)
203
+ while value.size>0
204
+ @segments << Segment.factory(value.is_packed, as4byte)
205
+ end
206
+ end
207
+
208
+ end
209
+
210
+ class As4_path < As_path
211
+ def initialize(*args)
212
+ super(*args)
213
+ @flags, @type, @as4byte =OPTIONAL_TRANSITIVE, AS4_PATH, true
214
+ end
215
+ def parse(s,as4byte=@as4byte)
216
+ super(s,true)
217
+ end
218
+ end
219
+
220
+ end
221
+
222
+ load "../test/#{ File.basename($0.gsub(/.rb/,'_test.rb'))}" if __FILE__ == $0
223
+
@@ -0,0 +1,42 @@
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
+ module BGP
27
+
28
+ class Atomic_aggregate < Attr
29
+ def initialize(arg=nil)
30
+ @flags, @type=OPTIONAL, ATOMIC_AGGREGATE
31
+ if arg.is_a?(String) and arg.is_packed?
32
+ parse(arg)
33
+ elsif arg.nil?
34
+ else
35
+ raise ArgumentError, "invalid argument, #{arg.class} #{arg}"
36
+ end
37
+ end
38
+ end
39
+
40
+ end
41
+
42
+ load "../test/#{ File.basename($0.gsub(/.rb/,'_test.rb'))}" if __FILE__ == $0