#!/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