bgp4r 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
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