[Ruby] I made a simple Ping client

Overview

I made a simple client that sends and receives ICMP Echo Requests only once, so before I forget, I made a note of what I learned at the time of implementation and what I was careful about.

Deliverable link

https://rubygems.org/gems/simple_ping https://github.com/kuredev/simple_ping

Purpose

--Practice of network programming --Practice of gem package release --Distraction

What / How to use

What you can do

--Return the success or failure of the ping (ICMP) result as true / false --The destination is specified as an IP address

Things impossible

--Specify destination by FQDN --Retry --Customization of transmitted data (ID specification, data part specification, etc.)

Usage sample

ping.rb


require "simple_ping"

ping_client = SimplePing::Client.new(src_ip_addr: "192.168.1.100")
puts ping_client.exec(dest_ip_addr: "192.168.1.101") ? "Success!" : "Failed.."

console


> sudo ruby ping.rb
Success!

Implementation memo

--You will be doing socket programming, but if you look at the Documentation, you will see some sockets. There are different types, but this time I will touch the ICMP header directly, so I will use SOCK_RAW (Raw socket). --When you finally send the data (send), you need to specify the data as a character string. There is. It is necessary to convert the prepared ICMP header data string into a character string one byte at a time according to the ASCII code. --For example, if the "identifier" is 65, 65 will be ʻAon the [ASCII code](http://www3.nit.ac.jp/~tamura/ex2/ascii.html), so ʻA You need to send. --On Ruby, you can get characters according to ASCII code by using 65.chr etc. Reference --However, note that the encoding type seems to be varies depending on the setting. --When receiving, it is received by recvfrom method, and the data can be obtained as a character string. --The acquired data is in the form of including the IP header. --Since the size of the IP header is basically 20 bytes (it seems that it may be different, but this time it is not assumed in the implementation), the ICMP header data can be acquired in order from the 21st byte. --For example, if it is the "type" at the beginning of the ICMP header, you can get it as follows. --You can convert a string to ASCII code with the bytes method

mesg, _ = socket.recvfrom(1500)
mesg[21].bytes[0] #=> 0

--At the time of reception, it is necessary to determine whether the received packet is the return packet of the transmitted item, but check the correspondence between transmission and reception by collating the "ID", "sequence number" and "type" (below). According to RFC)

The data contained in the received echo message must be returned as the data in the echo reply message. The identifier and sequence number are used by the echo sender to associate the echo request with its reply. An identifier may be used, for example the port number used by TCP or UDP to identify the session, or the sequence number may be incremented with each echo request. The echo-returning side returns the same value in the echo reply. http://srgia.com/docs/rfc792j.html

reference

I made various Sockets with Ruby and played with them. --Qiita https://qiita.com/MikuriyaHiroshi/items/b0a40f5e7b7be1ef327c

[Ruby] Network program using RawSocket – Euniclus https://euniclus.com/article/ruby-port-scan/

BasicSocket # send (Ruby 2.7.0 Reference Manual) https://docs.ruby-lang.org/ja/latest/method/BasicSocket/i/send.html

Internet Control Message Protocol - Wikipedia https://ja.wikipedia.org/wiki/Internet_Control_Message_Protocol#ICMP%E3%83%98%E3%83%83%E3%83%80

Convert ASCII code and characters (ord, chr, bytes, unpack, codepoints) | Makumaku Ruby Note https://maku77.github.io/ruby/number/ascii-char.html

RFC792(INTERNET CONTROL MESASAGE PROTOCOL) http://srgia.com/docs/rfc792j.html

Recommended Posts

[Ruby] I made a simple Ping client
Ruby: I made a FizzBuzz program!
I made a simple recommendation function.
I made a risky die with Ruby
I made a Ruby extension library in C
I made a portfolio with Ruby On Rails
I made a simple calculation problem game in Java
[Ruby] I made a crawler with anemone and nokogiri.
I made a chat app.
I made a Restful server and client in Spring.
I made a simple MVC sample system using Spring Boot
I made a shopify app @java
I made a GUI with Swing
Implement a gRPC client in Ruby
I made a matching app (Android app)
I made a package.xml generation tool.
[Android] I made a pedometer app.
[Rails] I made a simple calendar mini app with customized specifications.
I made a Ruby container image and moved the Lambda function
I made a simple search form with Spring Boot + GitHub Search API.
I tried a calendar problem in Ruby
I made various Fibonacci sequence functions (Ruby)
I made a plugin for IntelliJ IDEA
I made a rock-paper-scissors app with kotlin
I made a calculator app on Android
I made a new Java deployment tool
I made a rock-paper-scissors app with android
I made a bulletin board using Docker 1
I made a Diff tool for Java files
I made StringUtils.isBlank
I started Ruby
04. I made a front end with SpringBoot + Thymeleaf
I made a mosaic art with Pokemon images
java I tried to break a simple block
I made a gender selection column with enum
I made a THETA API client that can be used for plug-in development
[Ruby] I want to do a method jump!
I made blackjack with Ruby (I tried using minitest)
I made a rock-paper-scissors game in Java (CLI)
I made a viewer app that displays a PDF
I made a Docker container to run Maven
[Rails] I made a draft function using enum
I made an API client for Nature Remo
I made a simple graph library for smartphone apps [MP Android Chart Kai]
I made a LINE bot with Rails + heroku
I made a Docker image of SDAPS for Japanese
I made a check tool for the release module
I made my own Instagram automatic like tool [Ruby]
I tried to decorate the simple calendar a little
I made a method to ask for Premium Friday
I made a drawing chat "8bit paint chat" on WebAssembly
I made a library that works like a Safari tab !!
I made a library for displaying tutorials on Android.
I made a Wrapper that calls KNP from Java
I want to connect to Heroku MySQL from a client
I made a ruby script template that processes a huge file (even 1 million lines) line by line
I made a function to register images with API in Spring Framework. Part 2 (Client Edition)
I made a Japanese version of Rails / devise automatic email
I made a server side of an online card game ⑤
I made a development environment with rails6 + docker + postgreSQL + Materialize.
I made an interpreter (compiler?) With about 80 lines in Ruby.