12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394 |
- require_relative 'parser'
- def parse_for_aspath(stream)
- contributors = []
- relations = {}
- origins = {}
- meta = {}
- until stream.eof?
- record = Mrt::MrtRecord.read stream
- raise 'Unsupported type.' unless record.header.get_type == :TABLE_DUMP_V2
- case record.header.get_subtype
- when :PEER_INDEX_TABLE
- meta[:table] = record.data.view_name
- meta[:collector_router_id] = IPAddr.new(record.data.get_collector_router_id)
- record.data.peer_entries.each do |peer|
- if peer.peer_as != 0 && !contributors.include?(peer.peer_as)
- contributors << peer.peer_as
- end
- end
- when :RIB_IPV6_UNICAST, :RIB_IPV6_UNICAST_ADDPATH, :RIB_IPV4_UNICAST, :RIB_IPV4_UNICAST_ADDPATH
- prefix = "#{IPAddr.new(record.data.get_prefix)}/#{record.data.prefix_length}"
- # Begin loop rib entries
- record.data.rib_entries.each do |rib|
- rib.attributes.each do |attr|
- if attr.is_valid?
- case attr.get_type
- when :AS_PATH
- if attr.attribute.get_type == :AS_SEQUENCE
- # Add prefix to ASN
- aspath = attr.attribute.path_segment_value.to_a
- origins[prefix] = [] unless origins[prefix]
- unless origins[prefix].include? aspath.last
- puts "#{aspath.last} is announcing #{prefix}."
- origins[prefix] << aspath.last
- end
- # Add ASN relationsships
- for i in 0...(aspath.length - 1)
- relations[aspath[i]] = [] unless relations[aspath[i]]
- relations[aspath[i + 1]] = [] unless relations[aspath[i + 1]]
- unless relations[aspath[i]].include? aspath[i + 1]
- puts "AS#{aspath[i]} is a neighbor of AS#{aspath[i + 1]}."
- relations[aspath[i]] << aspath[i + 1]
- end
- relations[aspath[i + 1]] << aspath[i] unless relations[aspath[i + 1]].include? aspath[i]
- end
- end
- end
- end
- end
- end
- # End loop rib entries
- end
- end
- return [meta, contributors, relations, origins]
- end
- if ARGV[0]
- filename = ARGV[0]
- else
- puts 'No MRT file given. Assuming first mrt file.'
- filename = Dir['*.mrt'].first
- if filename
- puts "Using #{filename} as MRT file."
- else
- puts 'No MRT file found'
- exit 1
- end
- end
- unless File.readable? filename
- puts "File #{filename} is not readable."
- exit 1
- end
- file = File.new(filename, 'rb')
- result = parse_for_aspath file
- file.close
- puts "BGP Collector: #{result[0][:collector_router_id]}"
- puts "Table: #{result[0][:table]}"
- puts "Detected #{result[1].length} contributors."
- puts "Detected #{result[2].length} ASNs."
- puts "Detected #{result[3].length} prefixes."
|