跳轉到內容

ANTFARM/Traceroute/Traceroute 指令碼

來自華夏公益教科書,開放書籍,開放世界

此指令碼的目的是解析 traceroute 檔案並提取資訊,以供 Antfarm 的圖形檢視使用。

 #!/usr/bin/env ruby
 #
 # Copyright (2008) Sandia Corporation.
 # Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
 # the U.S. Government retains certain rights in this software.
 #
 # Original Author: Michael Berg, Sandia National Laboratories <mjberg@sandia.gov>
 # Modified By: Bryan T. Richardson, Sandia National Laboratories <btricha@sandia.gov>
 # Further Modifications By: Melissa Myerly & Cassandra Trevino, Sandia National Laboratories
 # This library is free software; you can redistribute it and/or modify it
 # under the terms of the GNU Lesser General Public License as published by
 # the Free Software Foundation; either version 2.1 of the License, or (at
 # your option) any later version.
 #
 # This library is distributed in the hope that it will be useful, but WITHOUT
 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 # details.
 #
 # You should have received a copy of the GNU Lesser General Public License
 # along with this library; if not, write to the Free Software Foundation, Inc.,
 # 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 
 #
 def parse(file)
 puts "Filename: "        #This is here for convenience, it simply prints the filename you are parsing to the screen.
 puts  file

使用正則表示式解析 traceroute 檔案。從 traceroute 檔案中解析出的專案包括主機名、時間、跳數和 IP 地址。本指令碼不使用時間或跳數專案。

  hostname_regexp =       Regexp.new('(\S+)\.[a-z]*(\d)*')
  time_regexp =           Regexp.new('(<*\d+\s*ms\s*){1,3}')
  hop_regexp   =          Regexp.new('(\d){1,3}')
  ipv4_regexp =           Regexp.new('((\d){1,3}\.(\d){1,3}\.(\d){1,3}\.(\d){1,3})')

所有用於在資料庫中儲存資料的專案都設定為 nil。

  hostname = nil
  source_addr = nil
  source_hostname = nil
  dest_addr = nil
  dest_hostname = nil
  list = File.open(file)
  firstline = list.gets()

對於 traceroute 檔案中的每一行,都會檢查資料庫中的記錄以確保主機名或 IP 地址不存在,以便可以將其新增到資料庫中。當從 traceroute 檔案中解析出每個 IP 地址和主機名時,就會發生這種情況。

  source_addr = ipv4_regexp.match(firstline)
  source_hostname = hostname_regexp.match(firstline)
  list.each do |line|
   dest_addr = ipv4_regexp.match(line)
   dest_hostname = hostname_regexp.match(line)
   if dest_hostname
     if ipv4_regexp.match( "#{dest_hostname}" )
         dest_hostname = nil
     end
   end 
   source_iface = IpInterface.find_or_initialize_by_address("#{source_addr}")
                 if source_iface.new_record?
                   source_iface.node_name = "#{source_addr}"      #Assign the node name in the database to the source address
                   source_iface.node_device_type = 'TRACEROUTE'   #Informing the database this is from TRACEROUTE data 
                   source_iface.save false
                 end
                 dest_iface = IpInterface.find_or_initialize_by_address("#{dest_addr}")
                 if dest_iface.new_record?
                   dest_iface.node_name = "#{dest_addr}"
                   dest_iface.node_device_type = 'TRACEROUTE'
                   dest_iface.save false
                 end

以下內容用於將從 traceroute 檔案中提取的資訊輸入資料庫。source_iface.layer3_interface.id 指的是源地址,dest_iface.layer3_interface.id 指的是目標地址。

   traffic = Traffic.first(:conditions => { :source_layer3_interface_id => source_iface.layer3_interface.id,
                                            :target_layer3_interface_id => dest_iface.layer3_interface.id })
  unless traffic
   traffic = Traffic.create :source_layer3_interface => source_iface.layer3_interface,
                            :target_layer3_interface => dest_iface.layer3_interface,
                            :description => "TRACEROUTE"
  end

以下 3 個 puts 語句不是必需的,它們用於方便起見,以及驗證正確的主機名和關聯的 IP 地址是否已放置到資料庫中的正確表中。

   puts "Source Hostname Addr  #{source_hostname}  #{source_addr} "
   puts "Dest Hostname Addr  #{dest_hostname}  #{dest_addr}"
   puts "end of line"

源地址和主機名必須成為迴圈的下一次迭代的目標地址和主機名(以及 Antfarm 生成的圖形的意義)。

    source_addr = dest_addr
    source_hostname = dest_hostname
   end
 end
 if ARGV[0] == '--help'
   #print_help
 else
   ARGV.each do |arg|
     if File.directory?(arg)
       Find.find(arg) do |path|
         if File.file?(path)
           parse(path)
         end
       end
     else
       parse(arg)
     end
   end
 end
華夏公益教科書