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.
- data/bgp/aggregator.rb +104 -0
 - data/bgp/as_path.rb +223 -0
 - data/bgp/atomic_aggregate.rb +42 -0
 - data/bgp/attribute.rb +181 -0
 - data/bgp/attributes.rb +34 -0
 - data/bgp/cluster_list.rb +117 -0
 - data/bgp/common.rb +204 -0
 - data/bgp/communities.rb +139 -0
 - data/bgp/extended_communities.rb +107 -0
 - data/bgp/extended_community.rb +254 -0
 - data/bgp/iana.rb +269 -0
 - data/bgp/io.rb +116 -0
 - data/bgp/label.rb +94 -0
 - data/bgp/local_pref.rb +75 -0
 - data/bgp/message.rb +894 -0
 - data/bgp/mp_reach.rb +208 -0
 - data/bgp/multi_exit_disc.rb +76 -0
 - data/bgp/neighbor.rb +291 -0
 - data/bgp/next_hop.rb +63 -0
 - data/bgp/nlri.rb +303 -0
 - data/bgp/orf.rb +88 -0
 - data/bgp/origin.rb +88 -0
 - data/bgp/originator_id.rb +73 -0
 - data/bgp/path_attribute.rb +210 -0
 - data/bgp/prefix_orf.rb +263 -0
 - data/bgp/rd.rb +107 -0
 - data/examples/bgp +65 -0
 - data/examples/routegen +85 -0
 - data/examples/routegen.yml +50 -0
 - data/test/aggregator_test.rb +66 -0
 - data/test/as_path_test.rb +149 -0
 - data/test/atomic_aggregate_test.rb +35 -0
 - data/test/attribute_test.rb +57 -0
 - data/test/cluster_list_test.rb +39 -0
 - data/test/common_test.rb +68 -0
 - data/test/communities_test.rb +75 -0
 - data/test/extended_communities_test.rb +111 -0
 - data/test/extended_community_test.rb +93 -0
 - data/test/label_test.rb +50 -0
 - data/test/local_pref_test.rb +43 -0
 - data/test/message_test.rb +294 -0
 - data/test/mp_reach_test.rb +143 -0
 - data/test/multi_exit_disc_test.rb +46 -0
 - data/test/neighbor_test.rb +50 -0
 - data/test/next_hop_test.rb +37 -0
 - data/test/nlri_test.rb +189 -0
 - data/test/origin_test.rb +57 -0
 - data/test/originator_id_test.rb +38 -0
 - data/test/path_attribute_test.rb +127 -0
 - data/test/prefix_orf_test.rb +97 -0
 - data/test/rd_test.rb +44 -0
 - metadata +84 -11
 
    
        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
         
     | 
    
        data/bgp/attribute.rb
    ADDED
    
    | 
         @@ -0,0 +1,181 @@ 
     | 
|
| 
      
 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/common'
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
            module BGP
         
     | 
| 
      
 26 
     | 
    
         
            +
              
         
     | 
| 
      
 27 
     | 
    
         
            +
              module ATTR
         
     | 
| 
      
 28 
     | 
    
         
            +
                
         
     | 
| 
      
 29 
     | 
    
         
            +
                ### http://www.iana.org/assignments/bgp-parameters/bgp-parameters.xhtml#bgp-parameters-2
         
     | 
| 
      
 30 
     | 
    
         
            +
                
         
     | 
| 
      
 31 
     | 
    
         
            +
                ORIGIN = 1
         
     | 
| 
      
 32 
     | 
    
         
            +
                AS_PATH = 2
         
     | 
| 
      
 33 
     | 
    
         
            +
                NEXT_HOP = 3
         
     | 
| 
      
 34 
     | 
    
         
            +
                MULTI_EXIT_DISC = 4
         
     | 
| 
      
 35 
     | 
    
         
            +
                LOCAL_PREF = 5
         
     | 
| 
      
 36 
     | 
    
         
            +
                ATOMIC_AGGREGATE = 6
         
     | 
| 
      
 37 
     | 
    
         
            +
                AGGREGATOR = 7
         
     | 
| 
      
 38 
     | 
    
         
            +
                COMMUNITIES = 8
         
     | 
| 
      
 39 
     | 
    
         
            +
                ORIGINATOR_ID = 9
         
     | 
| 
      
 40 
     | 
    
         
            +
                CLUSTER_LIST = 10
         
     | 
| 
      
 41 
     | 
    
         
            +
                
         
     | 
| 
      
 42 
     | 
    
         
            +
                MP_REACH = 14
         
     | 
| 
      
 43 
     | 
    
         
            +
                MP_UNREACH = 15
         
     | 
| 
      
 44 
     | 
    
         
            +
                EXTENDED_COMMUNITY = 16
         
     | 
| 
      
 45 
     | 
    
         
            +
                AS4_PATH = 17
         
     | 
| 
      
 46 
     | 
    
         
            +
                AS4_AGGREGATOR = 18
         
     | 
| 
      
 47 
     | 
    
         
            +
                
         
     | 
| 
      
 48 
     | 
    
         
            +
                SET = 1
         
     | 
| 
      
 49 
     | 
    
         
            +
                SEQUENCE = 2
         
     | 
| 
      
 50 
     | 
    
         
            +
                CONFED_SEQUENCE = 3
         
     | 
| 
      
 51 
     | 
    
         
            +
                CONFED_SET = 4
         
     | 
| 
      
 52 
     | 
    
         
            +
                
         
     | 
| 
      
 53 
     | 
    
         
            +
                OPTIONAL = 0x8
         
     | 
| 
      
 54 
     | 
    
         
            +
                TRANSITIVE = 0x4
         
     | 
| 
      
 55 
     | 
    
         
            +
                PARTIAL = 0x2
         
     | 
| 
      
 56 
     | 
    
         
            +
                EXTENDED_LENGTH = 0x1 
         
     | 
| 
      
 57 
     | 
    
         
            +
                NONE = 0x0
         
     | 
| 
      
 58 
     | 
    
         
            +
                
         
     | 
| 
      
 59 
     | 
    
         
            +
                WELL_KNOWN_MANDATORY     = TRANSITIVE
         
     | 
| 
      
 60 
     | 
    
         
            +
                WELL_KNOWN_DISCRETIONARY = TRANSITIVE
         
     | 
| 
      
 61 
     | 
    
         
            +
                OPTIONAL_TRANSITIVE      = OPTIONAL | TRANSITIVE
         
     | 
| 
      
 62 
     | 
    
         
            +
                OPTIONAL_NON_TRANSITIVE  = OPTIONAL
         
     | 
| 
      
 63 
     | 
    
         
            +
                
         
     | 
| 
      
 64 
     | 
    
         
            +
                def encode(value='',value_fmt=nil)
         
     | 
| 
      
 65 
     | 
    
         
            +
                  len, len_fmt = value.size, 'C'
         
     | 
| 
      
 66 
     | 
    
         
            +
                  if len>255
         
     | 
| 
      
 67 
     | 
    
         
            +
                    @flags |= EXTENDED_LENGTH
         
     | 
| 
      
 68 
     | 
    
         
            +
                    len_fmt='n'
         
     | 
| 
      
 69 
     | 
    
         
            +
                  end
         
     | 
| 
      
 70 
     | 
    
         
            +
                  if value_fmt
         
     | 
| 
      
 71 
     | 
    
         
            +
                    [@flags<<4, @type, len, *value].pack("CC#{len_fmt}#{value_fmt}")
         
     | 
| 
      
 72 
     | 
    
         
            +
                  else
         
     | 
| 
      
 73 
     | 
    
         
            +
                    ([@flags<<4, @type, len].pack("CC#{len_fmt}") + value).is_packed
         
     | 
| 
      
 74 
     | 
    
         
            +
                  end
         
     | 
| 
      
 75 
     | 
    
         
            +
                end
         
     | 
| 
      
 76 
     | 
    
         
            +
                
         
     | 
| 
      
 77 
     | 
    
         
            +
                def parse(*args)
         
     | 
| 
      
 78 
     | 
    
         
            +
                  _parse_(*args)
         
     | 
| 
      
 79 
     | 
    
         
            +
                end
         
     | 
| 
      
 80 
     | 
    
         
            +
                
         
     | 
| 
      
 81 
     | 
    
         
            +
                def _parse_(s,vf=nil)
         
     | 
| 
      
 82 
     | 
    
         
            +
                  value, arr = '', []
         
     | 
| 
      
 83 
     | 
    
         
            +
                  flags = s.unpack('C')[0]
         
     | 
| 
      
 84 
     | 
    
         
            +
                  if flags & 0x10>0
         
     | 
| 
      
 85 
     | 
    
         
            +
                    arr = s.unpack("CCn")
         
     | 
| 
      
 86 
     | 
    
         
            +
                    len = arr[2]
         
     | 
| 
      
 87 
     | 
    
         
            +
                    if vf
         
     | 
| 
      
 88 
     | 
    
         
            +
                      value = s[4..-1].unpack(vf)
         
     | 
| 
      
 89 
     | 
    
         
            +
                    else
         
     | 
| 
      
 90 
     | 
    
         
            +
                      value = s[4..-1].unpack("a#{len}")
         
     | 
| 
      
 91 
     | 
    
         
            +
                    end
         
     | 
| 
      
 92 
     | 
    
         
            +
                    s.slice!(0,arr[2]+4).is_packed
         
     | 
| 
      
 93 
     | 
    
         
            +
                  else
         
     | 
| 
      
 94 
     | 
    
         
            +
                    arr = s.unpack("CCC")
         
     | 
| 
      
 95 
     | 
    
         
            +
                    len = arr[2]
         
     | 
| 
      
 96 
     | 
    
         
            +
                    if vf
         
     | 
| 
      
 97 
     | 
    
         
            +
                      value = s[3..-1].unpack(vf)
         
     | 
| 
      
 98 
     | 
    
         
            +
                    else
         
     | 
| 
      
 99 
     | 
    
         
            +
                      value = s[3..-1].unpack("a#{len}")
         
     | 
| 
      
 100 
     | 
    
         
            +
                    end
         
     | 
| 
      
 101 
     | 
    
         
            +
                    s.slice!(0,arr[2]+3).is_packed
         
     | 
| 
      
 102 
     | 
    
         
            +
                  end
         
     | 
| 
      
 103 
     | 
    
         
            +
                  arr[0]= arr[0] >>4
         
     | 
| 
      
 104 
     | 
    
         
            +
                  value[0].is_packed unless vf
         
     | 
| 
      
 105 
     | 
    
         
            +
                  arr + value
         
     | 
| 
      
 106 
     | 
    
         
            +
                end
         
     | 
| 
      
 107 
     | 
    
         
            +
                
         
     | 
| 
      
 108 
     | 
    
         
            +
                def name
         
     | 
| 
      
 109 
     | 
    
         
            +
                  self.class.to_s.split('::').last
         
     | 
| 
      
 110 
     | 
    
         
            +
                end
         
     | 
| 
      
 111 
     | 
    
         
            +
                
         
     | 
| 
      
 112 
     | 
    
         
            +
                def flags
         
     | 
| 
      
 113 
     | 
    
         
            +
                  flags = @flags
         
     | 
| 
      
 114 
     | 
    
         
            +
                  s ="["
         
     | 
| 
      
 115 
     | 
    
         
            +
                  (flags&8>0) ? s +="O" : s += "w"
         
     | 
| 
      
 116 
     | 
    
         
            +
                  (flags&4>0) ? s +="T" : s += "n"
         
     | 
| 
      
 117 
     | 
    
         
            +
                  (flags&2>0) ? s +="P" : s += "c"
         
     | 
| 
      
 118 
     | 
    
         
            +
                  (flags&1>0) ? s +="E" : s += "r"
         
     | 
| 
      
 119 
     | 
    
         
            +
                  s +="]"
         
     | 
| 
      
 120 
     | 
    
         
            +
                end
         
     | 
| 
      
 121 
     | 
    
         
            +
                
         
     | 
| 
      
 122 
     | 
    
         
            +
                def flags_short
         
     | 
| 
      
 123 
     | 
    
         
            +
                  flags = @flags
         
     | 
| 
      
 124 
     | 
    
         
            +
                  s ="["
         
     | 
| 
      
 125 
     | 
    
         
            +
                  s +="O" if (flags&8>0)
         
     | 
| 
      
 126 
     | 
    
         
            +
                  s +="T" if (flags&4>0)
         
     | 
| 
      
 127 
     | 
    
         
            +
                  s +="P" if (flags&2>0)
         
     | 
| 
      
 128 
     | 
    
         
            +
                  s +="E" if (flags&1>0)
         
     | 
| 
      
 129 
     | 
    
         
            +
                  s +="]"
         
     | 
| 
      
 130 
     | 
    
         
            +
                end
         
     | 
| 
      
 131 
     | 
    
         
            +
                
         
     | 
| 
      
 132 
     | 
    
         
            +
                def attribute_name
         
     | 
| 
      
 133 
     | 
    
         
            +
                  name.split('_').collect { |w| w.capitalize }.join(' ')
         
     | 
| 
      
 134 
     | 
    
         
            +
                end
         
     | 
| 
      
 135 
     | 
    
         
            +
                
         
     | 
| 
      
 136 
     | 
    
         
            +
                def to_s(value='', mode=:tcpdump, as4byte=false)
         
     | 
| 
      
 137 
     | 
    
         
            +
                  
         
     | 
| 
      
 138 
     | 
    
         
            +
                  shex = as4byte ? to_shex4_len(20) : to_shex_len(20)
         
     | 
| 
      
 139 
     | 
    
         
            +
                  
         
     | 
| 
      
 140 
     | 
    
         
            +
                  mode = :brief unless [:tcpdump, :brief, :hexlify].include?(mode)
         
     | 
| 
      
 141 
     | 
    
         
            +
                  
         
     | 
| 
      
 142 
     | 
    
         
            +
                  case mode
         
     | 
| 
      
 143 
     | 
    
         
            +
                  when :brief
         
     | 
| 
      
 144 
     | 
    
         
            +
                    sprintf "%s %4s %10s: [%s]%s", flags, "(#{@type})", attribute_name, shex, "#{value.size>0 ? " '#{value}'" :''}"
         
     | 
| 
      
 145 
     | 
    
         
            +
                  when :hexlify
         
     | 
| 
      
 146 
     | 
    
         
            +
                    s = sprintf "%s %4s %10s: [%s]%s", flags, "(#{@type})", attribute_name, shex, "#{value.size>0 ? " '#{value}" :''}"
         
     | 
| 
      
 147 
     | 
    
         
            +
                    s +="\n\n"
         
     | 
| 
      
 148 
     | 
    
         
            +
                    if as4byte
         
     | 
| 
      
 149 
     | 
    
         
            +
                      s += self.encode4.hexlify.join("\n")
         
     | 
| 
      
 150 
     | 
    
         
            +
                    else
         
     | 
| 
      
 151 
     | 
    
         
            +
                      s += self.encode.hexlify.join("\n")
         
     | 
| 
      
 152 
     | 
    
         
            +
                    end
         
     | 
| 
      
 153 
     | 
    
         
            +
                  when :tcpdump
         
     | 
| 
      
 154 
     | 
    
         
            +
                    if as4byte
         
     | 
| 
      
 155 
     | 
    
         
            +
                      f, t, len, enc_value = _parse_(self.encode4, nil)
         
     | 
| 
      
 156 
     | 
    
         
            +
                    else
         
     | 
| 
      
 157 
     | 
    
         
            +
                      f, t, len, enc_value = _parse_(self.encode, nil)
         
     | 
| 
      
 158 
     | 
    
         
            +
                    end
         
     | 
| 
      
 159 
     | 
    
         
            +
                    s = sprintf "%s (%d), length: %d, Flags %s: %s", attribute_name, @type, len, flags_short, value
         
     | 
| 
      
 160 
     | 
    
         
            +
                    s += enc_value.hexlify.join(("\n   "))
         
     | 
| 
      
 161 
     | 
    
         
            +
                  end
         
     | 
| 
      
 162 
     | 
    
         
            +
                end
         
     | 
| 
      
 163 
     | 
    
         
            +
                
         
     | 
| 
      
 164 
     | 
    
         
            +
              end
         
     | 
| 
      
 165 
     | 
    
         
            +
             
     | 
| 
      
 166 
     | 
    
         
            +
              class Attr
         
     | 
| 
      
 167 
     | 
    
         
            +
                
         
     | 
| 
      
 168 
     | 
    
         
            +
                include ATTR
         
     | 
| 
      
 169 
     | 
    
         
            +
                include Comparable
         
     | 
| 
      
 170 
     | 
    
         
            +
                
         
     | 
| 
      
 171 
     | 
    
         
            +
                def method_missing(name, *args, &block)
         
     | 
| 
      
 172 
     | 
    
         
            +
                  if name == :encode4
         
     | 
| 
      
 173 
     | 
    
         
            +
                    send :encode, *args, &block
         
     | 
| 
      
 174 
     | 
    
         
            +
                  else
         
     | 
| 
      
 175 
     | 
    
         
            +
                    super
         
     | 
| 
      
 176 
     | 
    
         
            +
                  end
         
     | 
| 
      
 177 
     | 
    
         
            +
                end 
         
     | 
| 
      
 178 
     | 
    
         
            +
             
     | 
| 
      
 179 
     | 
    
         
            +
              end
         
     | 
| 
      
 180 
     | 
    
         
            +
             
     | 
| 
      
 181 
     | 
    
         
            +
            end
         
     | 
    
        data/bgp/attributes.rb
    ADDED
    
    | 
         @@ -0,0 +1,34 @@ 
     | 
|
| 
      
 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/origin'
         
     | 
| 
      
 24 
     | 
    
         
            +
            require 'bgp/next_hop'
         
     | 
| 
      
 25 
     | 
    
         
            +
            require 'bgp/local_pref'
         
     | 
| 
      
 26 
     | 
    
         
            +
            require 'bgp/multi_exit_disc'
         
     | 
| 
      
 27 
     | 
    
         
            +
            require 'bgp/as_path'
         
     | 
| 
      
 28 
     | 
    
         
            +
            require 'bgp/communities'
         
     | 
| 
      
 29 
     | 
    
         
            +
            require 'bgp/aggregator'
         
     | 
| 
      
 30 
     | 
    
         
            +
            require 'bgp/atomic_aggregate'
         
     | 
| 
      
 31 
     | 
    
         
            +
            require 'bgp/originator_id'
         
     | 
| 
      
 32 
     | 
    
         
            +
            require 'bgp/cluster_list'
         
     | 
| 
      
 33 
     | 
    
         
            +
            require 'bgp/mp_reach'
         
     | 
| 
      
 34 
     | 
    
         
            +
            require 'bgp/extended_communities'
         
     | 
    
        data/bgp/cluster_list.rb
    ADDED
    
    | 
         @@ -0,0 +1,117 @@ 
     | 
|
| 
      
 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 Cluster_list < Attr
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                ##########################################################
         
     | 
| 
      
 31 
     | 
    
         
            +
                # CLUSTER ID                                             #
         
     | 
| 
      
 32 
     | 
    
         
            +
                ##########################################################
         
     | 
| 
      
 33 
     | 
    
         
            +
                class Id
         
     | 
| 
      
 34 
     | 
    
         
            +
                  def initialize(id)
         
     | 
| 
      
 35 
     | 
    
         
            +
                    @id = IPAddr.create(id)
         
     | 
| 
      
 36 
     | 
    
         
            +
                  end
         
     | 
| 
      
 37 
     | 
    
         
            +
                  def to_s
         
     | 
| 
      
 38 
     | 
    
         
            +
                    @id.to_s
         
     | 
| 
      
 39 
     | 
    
         
            +
                  end
         
     | 
| 
      
 40 
     | 
    
         
            +
                  def to_i
         
     | 
| 
      
 41 
     | 
    
         
            +
                    @id.to_i
         
     | 
| 
      
 42 
     | 
    
         
            +
                  end
         
     | 
| 
      
 43 
     | 
    
         
            +
                  def encode
         
     | 
| 
      
 44 
     | 
    
         
            +
                    @id.hton
         
     | 
| 
      
 45 
     | 
    
         
            +
                  end
         
     | 
| 
      
 46 
     | 
    
         
            +
                end
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                ##########################################################
         
     | 
| 
      
 49 
     | 
    
         
            +
                # CLUSTER_LIST ATTRIBUTE                                 #
         
     | 
| 
      
 50 
     | 
    
         
            +
                ##########################################################
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
                def initialize(*args)
         
     | 
| 
      
 53 
     | 
    
         
            +
                  @flags, @type = OPTIONAL, CLUSTER_LIST
         
     | 
| 
      
 54 
     | 
    
         
            +
                  if args[0].is_a?(String) and args[0].is_packed?
         
     | 
| 
      
 55 
     | 
    
         
            +
                    parse(args[0])
         
     | 
| 
      
 56 
     | 
    
         
            +
                  elsif args[0].is_a?(self.class)
         
     | 
| 
      
 57 
     | 
    
         
            +
                    parse(args[0].encode, *args[1..-1])
         
     | 
| 
      
 58 
     | 
    
         
            +
                  else
         
     | 
| 
      
 59 
     | 
    
         
            +
                    add(*args)
         
     | 
| 
      
 60 
     | 
    
         
            +
                  end
         
     | 
| 
      
 61 
     | 
    
         
            +
                end
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
                def add(*args)
         
     | 
| 
      
 64 
     | 
    
         
            +
                  @cluster_ids ||=[]
         
     | 
| 
      
 65 
     | 
    
         
            +
                  args.flatten.each do |arg|
         
     | 
| 
      
 66 
     | 
    
         
            +
                    if arg.is_a?(String) and arg.split(' ').size>1
         
     | 
| 
      
 67 
     | 
    
         
            +
                      arg.split.each { |v| @cluster_ids << Id.new(v) }
         
     | 
| 
      
 68 
     | 
    
         
            +
                    elsif arg.is_a?(String) and arg.split(',').size>1
         
     | 
| 
      
 69 
     | 
    
         
            +
                      arg.split(',').each { |v| @cluster_ids << Id.new(v) }
         
     | 
| 
      
 70 
     | 
    
         
            +
                    elsif arg.is_a?(Id)
         
     | 
| 
      
 71 
     | 
    
         
            +
                      @cluster_ids << arg
         
     | 
| 
      
 72 
     | 
    
         
            +
                    else
         
     | 
| 
      
 73 
     | 
    
         
            +
                      @cluster_ids << Id.new(arg)
         
     | 
| 
      
 74 
     | 
    
         
            +
                    end
         
     | 
| 
      
 75 
     | 
    
         
            +
                  end
         
     | 
| 
      
 76 
     | 
    
         
            +
                end
         
     | 
| 
      
 77 
     | 
    
         
            +
                alias << add
         
     | 
| 
      
 78 
     | 
    
         
            +
                
         
     | 
| 
      
 79 
     | 
    
         
            +
                def cluster_list
         
     | 
| 
      
 80 
     | 
    
         
            +
                  @cluster_ids.collect { |comm| comm.to_s }.join(' ')
         
     | 
| 
      
 81 
     | 
    
         
            +
                end
         
     | 
| 
      
 82 
     | 
    
         
            +
                
         
     | 
| 
      
 83 
     | 
    
         
            +
                def to_s(method=:default)
         
     | 
| 
      
 84 
     | 
    
         
            +
                  super(cluster_list, method)
         
     | 
| 
      
 85 
     | 
    
         
            +
                end
         
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
      
 87 
     | 
    
         
            +
                def to_ary
         
     | 
| 
      
 88 
     | 
    
         
            +
                  @cluster_ids.collect { |c| c.to_i }
         
     | 
| 
      
 89 
     | 
    
         
            +
                end
         
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
      
 91 
     | 
    
         
            +
                def encode
         
     | 
| 
      
 92 
     | 
    
         
            +
                  super(@cluster_ids.collect { |comm| comm.encode }.join)
         
     | 
| 
      
 93 
     | 
    
         
            +
                end
         
     | 
| 
      
 94 
     | 
    
         
            +
             
     | 
| 
      
 95 
     | 
    
         
            +
                def parse(s)
         
     | 
| 
      
 96 
     | 
    
         
            +
                  @flags, @type, len, value=super(s)
         
     | 
| 
      
 97 
     | 
    
         
            +
                  self << value.unpack("N#{len/4}")
         
     | 
| 
      
 98 
     | 
    
         
            +
                end
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
      
 100 
     | 
    
         
            +
                def sort
         
     | 
| 
      
 101 
     | 
    
         
            +
                  Cluster_list.new(to_ary.sort)
         
     | 
| 
      
 102 
     | 
    
         
            +
                end
         
     | 
| 
      
 103 
     | 
    
         
            +
             
     | 
| 
      
 104 
     | 
    
         
            +
                def sort!
         
     | 
| 
      
 105 
     | 
    
         
            +
                  @cluster_ids = @cluster_ids.sort_by { |c| c.to_i }
         
     | 
| 
      
 106 
     | 
    
         
            +
                  self
         
     | 
| 
      
 107 
     | 
    
         
            +
                end
         
     | 
| 
      
 108 
     | 
    
         
            +
             
     | 
| 
      
 109 
     | 
    
         
            +
                def <=>(other)
         
     | 
| 
      
 110 
     | 
    
         
            +
                  self.sort.to_shex <=> other.sort.to_shex
         
     | 
| 
      
 111 
     | 
    
         
            +
                end
         
     | 
| 
      
 112 
     | 
    
         
            +
             
     | 
| 
      
 113 
     | 
    
         
            +
              end
         
     | 
| 
      
 114 
     | 
    
         
            +
             
     | 
| 
      
 115 
     | 
    
         
            +
            end
         
     | 
| 
      
 116 
     | 
    
         
            +
             
     | 
| 
      
 117 
     | 
    
         
            +
            load "../test/#{ File.basename($0.gsub(/.rb/,'_test.rb'))}" if __FILE__ == $0
         
     |