Class: Net::Ping::ICMP
Overview
The Net::Ping::ICMP class encapsulates an icmp ping.
Constant Summary
- ICMP_ECHOREPLY =
0- ICMP_ECHO =
Echo reply Echo request
8- ICMP_SUBCODE =
0
Constants inherited from Net::Ping
Instance Attribute Summary (collapse)
-
- (Object) data_size
Returns the data size, i.e.
Attributes inherited from Net::Ping
#duration, #exception, #host, #port, #timeout, #warning
Instance Method Summary (collapse)
-
- (Object) bind(host, port = 0)
Associates the local end of the socket connection with the given host and port.
-
- (ICMP) initialize(host = nil, port = nil, timeout = 5)
constructor
Creates and returns a new Ping::ICMP object.
-
- (Object) ping(host = @host)
(also: #ping?, #pingecho)
Pings the host specified in this method or in the constructor.
Constructor Details
- (ICMP) initialize(host = nil, port = nil, timeout = 5)
Creates and returns a new Ping::ICMP object. This is similar to its superclass constructor, but must be created with root privileges (on UNIX systems), and the port value is ignored.
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/net/ping/icmp.rb', line 32 def initialize(host=nil, port=nil, timeout=5) raise 'requires root privileges' if Process.euid > 0 if File::ALT_SEPARATOR && windows_version >= 6 unless Win32::Security.elevated_security? raise 'requires elevated security' end end @seq = 0 @bind_port = 0 @bind_host = nil @data_size = 56 @data = '' 0.upto(@data_size){ |n| @data << (n % 256).chr } @pid = Process.pid & 0xffff super(host, port, timeout) @port = nil # This value is not used in ICMP pings. end |
Instance Attribute Details
- (Object) data_size
Returns the data size, i.e. number of bytes sent on the ping. The default size is 56.
26 27 28 |
# File 'lib/net/ping/icmp.rb', line 26 def data_size @data_size end |
Instance Method Details
- (Object) bind(host, port = 0)
Associates the local end of the socket connection with the given host and port. The default port is 0.
66 67 68 69 |
# File 'lib/net/ping/icmp.rb', line 66 def bind(host, port = 0) @bind_host = host @bind_port = port end |
- (Object) ping(host = @host) Also known as: ping?, pingecho
Pings the host specified in this method or in the constructor. If a host was not specified either here or in the constructor, an ArgumentError is raised.
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 |
# File 'lib/net/ping/icmp.rb', line 75 def ping(host = @host) super(host) bool = false socket = Socket.new( Socket::PF_INET, Socket::SOCK_RAW, Socket::IPPROTO_ICMP ) if @bind_host saddr = Socket.pack_sockaddr_in(@bind_port, @bind_host) socket.bind(saddr) end @seq = (@seq + 1) % 65536 pstring = 'C2 n3 A' << @data_size.to_s timeout = @timeout checksum = 0 msg = [ICMP_ECHO, ICMP_SUBCODE, checksum, @pid, @seq, @data].pack(pstring) checksum = checksum(msg) msg = [ICMP_ECHO, ICMP_SUBCODE, checksum, @pid, @seq, @data].pack(pstring) begin saddr = Socket.pack_sockaddr_in(0, host) rescue Exception socket.close unless socket.closed? return bool end start_time = Time.now socket.send(msg, 0, saddr) # Send the message begin Timeout.timeout(@timeout){ while true io_array = select([socket], nil, nil, timeout) if io_array.nil? || io_array[0].empty? return false end pid = nil seq = nil data = socket.recvfrom(1500).first type = data[20, 2].unpack('C2').first case type when ICMP_ECHOREPLY if data.length >= 28 pid, seq = data[24, 4].unpack('n3') end else if data.length > 56 pid, seq = data[52, 4].unpack('n3') end end if pid == @pid && seq == @seq && type == ICMP_ECHOREPLY bool = true break end end } rescue Exception => err @exception = err ensure socket.close if socket end # There is no duration if the ping failed @duration = Time.now - start_time if bool return bool end |