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