Last active
March 21, 2020 15:35
-
-
Save yantene/7be11d07ea60feb5e29d to your computer and use it in GitHub Desktop.
Ruby で ping を行うプログラムです. 嘘つきました.応答の受信機能はありません.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'socket' | |
class ICMPEchoMessage | |
TYPE = 0x08 | |
CODE = 0x00 | |
def initialize(id = rand(0..0xffff)) | |
@id = id.freeze | |
@seq = 0x0000 | |
@socket = Socket.open( | |
Socket::PF_INET, # IPv4 | |
Socket::SOCK_RAW, # RAW Socket | |
Socket::IPPROTO_ICMP # ICMP | |
) | |
end | |
def send(dest_host, data) | |
dest = Socket.sockaddr_in(nil, dest_host) | |
@socket.send(packet_data(@seq += 1, data).pack('C*'), 0, dest) | |
end | |
private | |
def packet_data(seq, data, csum = checksum(seq, data)) | |
[TYPE, CODE] + | |
to_bytes(csum, 2) + | |
to_bytes(@id, 2) + | |
to_bytes(seq, 2) + | |
data | |
end | |
# calcurate checksum | |
def checksum(seq, data) | |
to_bytes( | |
packet_data(seq, data, 0).each_slice(2).inject(0) do |m, i| | |
m + to_num((i << 0)[0, 2]) | |
end | |
).each_slice(2).to_a.reverse.inject(0) do |m, i| | |
m + to_num(i.reverse) | |
end ^ 0xffff | |
end | |
# Fixnum to byte array | |
def to_bytes(num, size = (num.bit_length / 8.0).ceil) | |
Array.new(size) do |i| | |
(num >> (i * 8)) & 0xff | |
end.reverse | |
end | |
# Byte array to fixnum | |
def to_num(bytes) | |
bytes.inject { |m, i| (m << 8) + i } | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require './icmp_echo_message' | |
# 送信先ホスト | |
host = ARGV[0] | |
# 送信間隔 [ms] | |
sleep = ARGV[1] || 1000 | |
# エポック秒を逆順のバイト配列にしたもの | |
timestamp = -> do | |
now = Time.now.to_i | |
Array.new(8) { |i| (now >> (i * 8)) & 0xff } | |
end.call | |
ping = ICMPEchoMessage.new | |
loop do | |
ping.send(host, timestamp) | |
sleep sleep / 1000.0 | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment