main.rb 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. require_relative 'parser'
  2. def parse_for_aspath(stream)
  3. contributors = []
  4. relations = {}
  5. origins = {}
  6. meta = {}
  7. until stream.eof?
  8. record = Mrt::MrtRecord.read stream
  9. raise 'Unsupported type.' unless record.header.get_type == :TABLE_DUMP_V2
  10. case record.header.get_subtype
  11. when :PEER_INDEX_TABLE
  12. meta[:table] = record.data.view_name
  13. meta[:collector_router_id] = IPAddr.new(record.data.get_collector_router_id)
  14. record.data.peer_entries.each do |peer|
  15. if peer.peer_as != 0 && !contributors.include?(peer.peer_as)
  16. contributors << peer.peer_as
  17. end
  18. end
  19. when :RIB_IPV6_UNICAST, :RIB_IPV6_UNICAST_ADDPATH, :RIB_IPV4_UNICAST, :RIB_IPV4_UNICAST_ADDPATH
  20. prefix = "#{IPAddr.new(record.data.get_prefix)}/#{record.data.prefix_length}"
  21. # Begin loop rib entries
  22. record.data.rib_entries.each do |rib|
  23. rib.attributes.each do |attr|
  24. if attr.is_valid?
  25. case attr.get_type
  26. when :AS_PATH
  27. if attr.attribute.get_type == :AS_SEQUENCE
  28. # Add prefix to ASN
  29. aspath = attr.attribute.path_segment_value.to_a
  30. origins[prefix] = [] unless origins[prefix]
  31. unless origins[prefix].include? aspath.last
  32. puts "#{aspath.last} is announcing #{prefix}."
  33. origins[prefix] << aspath.last
  34. end
  35. # Add ASN relationsships
  36. for i in 0...(aspath.length - 1)
  37. relations[aspath[i]] = [] unless relations[aspath[i]]
  38. relations[aspath[i + 1]] = [] unless relations[aspath[i + 1]]
  39. unless relations[aspath[i]].include? aspath[i + 1]
  40. puts "AS#{aspath[i]} is a neighbor of AS#{aspath[i + 1]}."
  41. relations[aspath[i]] << aspath[i + 1]
  42. end
  43. relations[aspath[i + 1]] << aspath[i] unless relations[aspath[i + 1]].include? aspath[i]
  44. end
  45. end
  46. end
  47. end
  48. end
  49. end
  50. # End loop rib entries
  51. end
  52. end
  53. return [meta, contributors, relations, origins]
  54. end
  55. if ARGV[0]
  56. filename = ARGV[0]
  57. else
  58. puts 'No MRT file given. Assuming first mrt file.'
  59. filename = Dir['*.mrt'].first
  60. if filename
  61. puts "Using #{filename} as MRT file."
  62. else
  63. puts 'No MRT file found'
  64. exit 1
  65. end
  66. end
  67. unless File.readable? filename
  68. puts "File #{filename} is not readable."
  69. exit 1
  70. end
  71. file = File.new(filename, 'rb')
  72. result = parse_for_aspath file
  73. file.close
  74. puts "BGP Collector: #{result[0][:collector_router_id]}"
  75. puts "Table: #{result[0][:table]}"
  76. puts "Detected #{result[1].length} contributors."
  77. puts "Detected #{result[2].length} ASNs."
  78. puts "Detected #{result[3].length} prefixes."