Class: Win32::PingICMP
- Inherits:
-
Object
- Object
- Win32::PingICMP
- Defined in:
- lib/win32/ping.rb
Constant Summary collapse
- IPFLAG_DONT_FRAGMENT =
0x02
- REPLY_BUFFER_SIZE =
1024
- ICMP_ECHO_REPLY_SIZE =
28
- @@icmp_create_file =
Win32API.new( 'icmp', 'IcmpCreateFile', '', 'N' )
- @@icmp_send_echo =
Win32API.new( 'icmp', 'IcmpSendEcho', 'NNPIPPNN', 'N' )
- @@icmp_close_handle =
Win32API.new( 'icmp', 'IcmpCloseHandle', 'N', 'I' )
- @@resolv =
Resolv.new
Class Method Summary collapse
-
.create_buffer(size) ⇒ Object
Some algorythm I found on line.
-
.icmp_close_handle(handle) ⇒ Object
Low level.
-
.icmp_create_file ⇒ Object
Low level, you probably shouldn’t be using it.
-
.icmp_send_echo(handle, int_ip, request_data, request_options, reply_buffer, timeout) ⇒ Object
This is pretty low level and probably shouldn’t be used, but since I believe in freedom, I have left it public just in case.
-
.resolv(hostname) ⇒ Object
Low level.
Instance Method Summary collapse
-
#ping(host, count = 1, size = 32, no_frag = false, ttl = 64, timeout = 4000) ⇒ Object
heres what you want.
Class Method Details
.create_buffer(size) ⇒ Object
Some algorythm I found on line. This generates the buffer to ping with
75 76 77 78 79 80 81 82 83 |
# File 'lib/win32/ping.rb', line 75 def self.create_buffer size b = [] 1.upto size do |i| # readable characters b << i % 94 + 32 end ("%c"*size)%b end |
.icmp_close_handle(handle) ⇒ Object
Low level. Are you sure you need this?
64 65 66 |
# File 'lib/win32/ping.rb', line 64 def self.icmp_close_handle handle @@icmp_close_handle.call( handle ) end |
.icmp_create_file ⇒ Object
Low level, you probably shouldn’t be using it
39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/win32/ping.rb', line 39 def self.icmp_create_file handle = @@icmp_create_file.call if block_given? begin yield handle ensure icmp_close_handle handle handle = nil end end handle end |
.icmp_send_echo(handle, int_ip, request_data, request_options, reply_buffer, timeout) ⇒ Object
This is pretty low level and probably shouldn’t be used, but since I believe in freedom, I have left it public just in case. I left out the data size and buffer size args because ruby can figure that out. int_ip is the int form of the ip address.
56 57 58 59 60 61 |
# File 'lib/win32/ping.rb', line 56 def self.icmp_send_echo handle, int_ip, request_data, , reply_buffer, timeout @@icmp_send_echo.call( handle, int_ip, request_data, request_data.size, , reply_buffer, reply_buffer.size, timeout ) end |
.resolv(hostname) ⇒ Object
Low level.
69 70 71 |
# File 'lib/win32/ping.rb', line 69 def self.resolv hostname @@resolv.getaddress hostname end |
Instance Method Details
#ping(host, count = 1, size = 32, no_frag = false, ttl = 64, timeout = 4000) ⇒ Object
heres what you want
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 |
# File 'lib/win32/ping.rb', line 86 def ping host, count = 1, size = 32, no_frag = false, ttl = 64, timeout = 4000 ip = nil nresolv = false begin if nresolv host = self.class.resolv host end ip = IPAddr.new( host ) rescue unless nresolv nresolv = true retry end raise $! end reply_buffer = "0" * ( size + ICMP_ECHO_REPLY_SIZE ) req_data = self.class.create_buffer size replies = [] no_frag = no_frag ? IPFLAG_DONT_FRAGMENT : 0 # struct options # u_char ttl # u_char tos # u_char flags # u_char options_size = ("%c"*4)%[ttl,0,no_frag,0] self.class.icmp_create_file do |handle| count.times do reply = OpenStruct.new reply.reply_count = self.class.icmp_send_echo( handle, ip.to_w32ip, req_data, , reply_buffer, timeout ) reply.request_data = req_data reply.reply_data = reply_buffer[28..-1] header = reply_buffer.unpack( 'NLLSSLCCCCL' ) reply.ip = header[0].to_ip reply.status, reply.round_trip_time = header[1..2] reply.data_size, reply.reserved = header[3..4] # this is a pointer to the actual reply data. We assume # that it is a 28 so we don't need it, maybe future versions # will #reply.pdata = header[5] reply.time_to_live = reply.ttl = header[6] reply.type_of_service = reply.tos = header[7] reply.flags = header[8] reply. = header[9] # this is a pointer to the optiondata, we don't need it # but maybe future versions will #reply.poptions_data = header[10] # I was using this one for testing #reply.reply_buffer = reply_buffer reply.successful = ( reply.status == 0 ) replies << reply end end def replies.all_successful? self.find {|r| !r.successful }.nil? end def replies.one_successful? !self.find {|r| r.successful}.nil? end replies end |