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