#!/usr/bin/env ruby

require 'icmp'

include ICMPModule
include Socket::Constants

host = ARGV.shift || 'localhost'
ent = Socket::gethostbyname(host)

ips = "%d.%d.%d.%d" % [ent[3][0], ent[3][1], ent[3][2], ent[3][3]]
print "PING #{ent[0]} (#{ips})\n"

# open ICMP socket.
sock = ICMPSocket.new
sockaddr = make_sockaddr_in(AF_INET, 0, ent[3])

# make ICMP packet.
req = ICMP.new
req.icmp_type = ICMP_ECHO
req.icmp_code = 0
req.icmp_id = $$ & 0xffff

Thread.start do
  loop do
    buf = sock.recv(65535)
    recv_time = Time.now.to_f
    iph, repl = ICMPModule.split(buf)

    if repl.icmp_type == ICMP_ECHOREPLY && repl.icmp_id == req.icmp_id
      send_time = repl.icmp_data.unpack("d")[0]
      rtt = (recv_time - send_time) * 1000
      print "%d bytes from %s: icmp_seq=%d time=%.3f ms\n" %
	[repl.size, iph.ip_src, repl.icmp_seq, rtt]
    end
  end
end

1000.times { |i|
  req.icmp_seq = i
  req.icmp_data = [ Time.now.to_f ].pack("d")
  req.setup   # calc checksum and config packet length.
  sock.send(req, 0, sockaddr)
  sleep 1
}


syntax highlighted by Code2HTML, v. 0.9.1