From: Bill Kelly Date: 2008-04-18T08:39:25+09:00 Subject: Re: system(ping) ------=_NextPart_000_0168_01C8A0A9.E6AFD7A0 Content-Type: text/plain; format=flowed; charset="utf-8"; reply-type=original Content-Transfer-Encoding: 8bit Hi, From: "Heinrich Piard" > I単aki Baz Castillo wrote: >> >> require 'ping' >> >> ip_list.each do { |ip| Ping.pingecho(ip, 3) } > > This Class does not support ICMP pings. For what it's worth, here's a traceroute in ruby that uses ICMP: http://code.google.com/p/rubyroute/ (The program is very short, so I've attached it to this email.) Regards, Bill ------=_NextPart_000_0168_01C8A0A9.E6AFD7A0 Content-Type: application/octet-stream; name="rubyroute.rb" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="rubyroute.rb" #!/usr/bin/ruby=0A= =0A= require 'timeout'=0A= require 'socket'=0A= include Socket::Constants=0A= =0A= def random_port=0A= 1024 + rand(64511)=0A= end=0A= =0A= if ARGV[0].nil?=0A= puts "Usage: rubyroute host" ; exit 1 =0A= end=0A= =0A= begin=0A= myname =3D Socket.gethostname =0A= rescue SocketError =3D> err_msg=0A= puts "Can't get my own host name (#{err_msg})." ; exit 1=0A= end=0A= =0A= puts "Tracing route to #{ARGV[0]}"=0A= =0A= ttl =3D 1=0A= max_ttl =3D 255=0A= localport =3D random_port=0A= dgram_sock =3D UDPSocket::new=0A= =0A= begin=0A= dgram_sock.bind( myname, localport )=0A= rescue =0A= localport =3D random_port=0A= retry=0A= end=0A= =0A= icmp_sock =3D Socket.open( Socket::PF_INET, Socket::SOCK_RAW, = Socket::IPPROTO_ICMP )=0A= icmp_sockaddr =3D Socket.pack_sockaddr_in( localport, myname )=0A= icmp_sock.bind( icmp_sockaddr )=0A= =0A= begin=0A= dgram_sock.connect( ARGV[0], 999 )=0A= rescue SocketError =3D> err_msg=0A= puts "Can't connect to remote host (#{err_msg})." ; exit 1=0A= end=0A= =0A= until ttl =3D=3D max_ttl=0A= dgram_sock.setsockopt( 0, Socket::IP_TTL, ttl )=0A= dgram_sock.send( "RubyRoute says hello!", 0 )=0A= =0A= begin=0A= Timeout::timeout( 1 ) {=0A= data, sender =3D icmp_sock.recvfrom( 8192 )=0A= # 20th and 21th bytes of IP+ICMP datagram carry the ICMP type and = code resp.=0A= icmp_type =3D data.unpack( '@20C' )[0]=0A= icmp_code =3D data.unpack( '@21C' )[0]=0A= # Extract the ICMP sender from response.=0A= puts "TTL =3D #{ttl}: " + Socket.unpack_sockaddr_in( sender )[1].to_s=0A= if ( icmp_type =3D=3D 3 and icmp_code =3D=3D 13 )=0A= puts "'Communication Administratively Prohibited' from this hop."=0A= # ICMP 3/3 is port unreachable and usually means that we've hit the = target.=0A= elsif ( icmp_type =3D=3D 3 and icmp_code =3D=3D 3 )=0A= puts "Destination reached. Trace complete."=0A= exit 0=0A= end=0A= }=0A= rescue Timeout::Error=0A= puts "Timeout error with TTL =3D #{ttl}!"=0A= end=0A= =0A= ttl +=3D 1=0A= end=0A= ------=_NextPart_000_0168_01C8A0A9.E6AFD7A0--