Ruby/Pcap + Wireshark

libpcapのrubyバインドのRuby/Pcapがあまりにも便利だということに、いまさらながら気づきました。Wireshark(tcpdumpでもいいけど)でキャプチャしたトラフィックを、そのままファイルに保存して、Ruby/Pcapに食わせて(そのまま使えるので)、TCPペイロードだけとかを、タイムスタンプを見ながら出力するようにする、とかすると、そのトラフィックの再現が容易にできます。あるいはWiresharkでも取れないような細かな統計を取ったりするのとかも簡単に書けます。

例えば超シンプルに、traffic.capファイルを食わせたいときは以下のような感じにすると、コンソールに全TCPパケットのソースアドレス等を表示できたりします。

#!/usr/bin/env ruby -wKU

require 'pcap'

cap = Pcap::Capture.open_offline(ARGV.shift || 'traffic.cap')
cap.setfilter("ip")
cap.loop do |pkt|
  if pkt.ip? and pkt.tcp?
    print "#{pkt.time.to_f.to_s} #{pkt.size}(#{pkt.tcp_data_len}): " +  
        "#{pkt.ip_src.to_s}:#{pkt.tcp_sport} -> #{pkt.ip_dst.to_s}:#{pkt.tcp_dport}: " + 
        "#{pkt.tcp_flags_s}\n"
  end
end
cap.close

Rubyでバイナリいじるのはpack/unpackの嵐になるけど、まあCで書くよりは全然ましです。Hexでdumpしたいときは、 hexdump.rb とか使えばOK。これは、このファイルをrequireすると、Stringクラスなオブジェクト(普通はすべてバイナリのバッファはString。たとえばIO.read/writeにそのまま使えるので便利)に.hexdumpできて、標準出力にHexでdumpすることができます。これがあればほとんど怖いものなしでしょう。