mirror of
https://github.com/cyberarm/w3d_hub_linux_launcher.git
synced 2026-03-22 04:06:18 +00:00
Initial work on UDP mode ICMP ping (https://keith.github.io/xcode-man-pages/icmp.4.html#Non-privileged_ICMP)
This commit is contained in:
70
lib/ping.rb
Normal file
70
lib/ping.rb
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
require "socket"
|
||||||
|
|
||||||
|
ICMPHeader = Data.define(:type, :code, :checksum, :_ping_id, :_sequence_id, :data)
|
||||||
|
|
||||||
|
ICMP_ECHOREPLY = 0 # Echo reply
|
||||||
|
ICMP_ECHO = 8 # Echo request
|
||||||
|
ICMP_SUBCODE = 0
|
||||||
|
|
||||||
|
# Perform a checksum on the message. This is the sum of all the short
|
||||||
|
# words and it folds the high order bits into the low order bits.
|
||||||
|
#
|
||||||
|
def checksum(msg)
|
||||||
|
length = msg.length
|
||||||
|
num_short = length / 2
|
||||||
|
check = 0
|
||||||
|
|
||||||
|
msg.unpack("n#{num_short}").each do |short|
|
||||||
|
check += short
|
||||||
|
end
|
||||||
|
|
||||||
|
if (length % 2).positive?
|
||||||
|
check += msg[length-1, 1].unpack1("C") << 8
|
||||||
|
end
|
||||||
|
|
||||||
|
check = (check >> 16) + (check & 0xffff)
|
||||||
|
~((check >> 16) + check) & 0xffff
|
||||||
|
end
|
||||||
|
|
||||||
|
ip_address = "127.0.0.1" # "example.com" # "timecrafters.org" #
|
||||||
|
@ping_id = 92_459_064_892 & 0xffff
|
||||||
|
@sequence = 1 % 65_536
|
||||||
|
data = ""
|
||||||
|
data_size = 56
|
||||||
|
data_size.times { |n| data << (n % 256).chr }
|
||||||
|
|
||||||
|
check = 0
|
||||||
|
packer = "C2 n3 A" << data_size.to_s
|
||||||
|
message = [ICMP_ECHO, ICMP_SUBCODE, check, @ping_id, @sequence, data].pack(packer)
|
||||||
|
check = checksum(message)
|
||||||
|
message = [ICMP_ECHO, ICMP_SUBCODE, check, @ping_id, @sequence, data].pack(packer)
|
||||||
|
message_header = ICMPHeader.new(*[ICMP_ECHO, ICMP_SUBCODE, check, @ping_id, @sequence, data])
|
||||||
|
socket = Socket.new(Socket::AF_INET, Socket::SOCK_DGRAM, Socket::IPPROTO_ICMP)
|
||||||
|
socket.send(message, 0, Socket.pack_sockaddr_in(0, ip_address))
|
||||||
|
s = Time.now
|
||||||
|
loop do
|
||||||
|
data, _addrinfo = socket.recvfrom(1500)
|
||||||
|
pp [message, data]
|
||||||
|
header = ICMPHeader.new(*data.unpack("C2 n3 A*"))
|
||||||
|
pp [message_header, header]
|
||||||
|
# reply_type = data[20, 2].unpack1("C2")
|
||||||
|
# pp reply_type
|
||||||
|
|
||||||
|
ping_id = header._ping_id
|
||||||
|
sequence = header._sequence_id
|
||||||
|
|
||||||
|
case header.type
|
||||||
|
when ICMP_ECHOREPLY
|
||||||
|
puts "ECHOREPLY"
|
||||||
|
end
|
||||||
|
|
||||||
|
pp [@ping_id, ping_id]
|
||||||
|
pp [@sequence, sequence]
|
||||||
|
|
||||||
|
if ping_id == @ping_id && sequence == @sequence && reply_type == ICMP_ECHOREPLY
|
||||||
|
puts "PING OKAY: #{Time.now - s}s"
|
||||||
|
break
|
||||||
|
end
|
||||||
|
|
||||||
|
break
|
||||||
|
end
|
||||||
Reference in New Issue
Block a user