ping is a network tool that is widely used to test the quality and stability of network connections. When we want to know if our computer is able to communicate with other devices or servers, ping is our best friend. The ping tool is also often used to measure the connectivity and network quality between networks when we want to detect them, as it is a small but powerful network diagnostic tool that often comes with the operating system.
ping was originally developed by Mike Muuss in 1983 for Unix systems. It got its name from the sonar system of a Navy submarine, which determines the location of a target by sending a sound wave and measuring its return time. ping works similarly by sending a small packet of data to a target device and then waiting for that device to return a response to measure its response time and latency.
When we use Ping to test a network connection, it can tell us two important metrics: latency and packet loss. Latency is the time it takes from sending a ping request to receiving a response, usually measured in milliseconds. Packet loss rate is the percentage of packets lost between the ping request and the response. If the packet loss rate is too high, it indicates that there may be problems with the network connection, resulting in unstable or even unreachable data transmission.
In addition to the basic ping command, there are many other ping commands and options available. For example, you can use the “-c” option to specify the number of ping requests to send, and the “-i” option to specify the time interval between ping requests. In addition, the “-s” option can be used to specify the packet size for sending ping requests.
Although ping is a very useful tool, it has some limitations. ping test results can be affected by many factors, such as network congestion, firewalls, router drops, and so on. In addition, some devices or servers may have disabled responses to ping requests, so the results of the ping test are not available.
Despite its limitations, it is still one of the must-have tools for network administrators and users.
Principle of implementation
The ping tool is based on rfc 792 (ICMP protocol). It is a document called “Internet Control Message Protocol (ICMP) Specification”, published by Jon Postel and J. Reynolds in September 1981. This document defines the ICMP protocol, which is an important part of the TCP/IP network protocol suite.
The ICMP protocol is a network layer protocol that is used to transport messages related to network control and error handling. The protocol is often used in conjunction with the IP protocol to exchange information over the Internet. rfc 792 details the different message types in the ICMP protocol and their uses. ping is implemented using sending an Echo request to get an Echo Reply.
|
|
where:
- type: 8 for echo message, 0 for echo reply message
- code: always 0
- checksum: checksum of the whole message
- Identifier: used to match echo and reply, we often use process ID
- Sequence Number: is also used to match echo and reply, for example, the same process ID, different sequence number represents different echo
- Data: payload value. So we can use a certain size of data when we use ping to test MTU or whatever
ICMP is encapsulated in IP packets for transmission.
We will also introduce ICMP when we introduce the traceroute tool implementation in the next article.
For ping, it is simply sending an echo message, calculating the time delay after receiving the corresponding echo reply message, and calculating a packet loss if the reply is not received after the timeout.
For example, we often use the ping command, which displays packet receipt and delay, you can specify the total number of packets sent, and there is a statistic at the end.
The introduction and examples in this article are for IPV4, IPv6 is similar but a bit different.
If you search ping.c
, you can easily find a ping tool implemented in C. If you use Go, there are also several ways to implement it.
“Cheat” method
The easiest way to implement this is to call the ping tool that comes with the operating system.
A few simple lines of code.
Using golang.org/x/net/icmp
Go’s net extension library specifically implements the icmp protocol. We can use it to implement pings.
If you use SOCK_RAW
for pinging, you need cap_net_raw permission, you can set it with the following command.
|
|
In Linux 3.0 new implementation there is a socket way to enable normal users to execute ping commands as well.
|
|
But you also need to set the following.
|
|
First, we implement the non-privileged ping
method of pinging. The icmp package does the wrapping for us, so we don’t have to use the underlying socket
, but use icmp.ListenPacket("udp4", "0.0.0.0")
to do it directly.
The complete code is as follows:
|
|
The key codes are commented out, mainly paying attention to the parsing of reply packets and the judgment of reply packets. Especially the reply packet judgment, we need to pay particular attention to this point when implementing traceroute in the next chapter.
Implementing with ip4:icmp
Even if we want to implement privileged ping, we don’t need to use raw socket directly, we still use icmp packets.
In this scenario, our network needs to be ip4:icmp
, capable of sending ICMP packets, not udp4
as above.
|
|
and the above example, mainly the logic of sending is not the same, much the same, send the amount of content are ICMP Echo message, only this time to send the failure, the address is not a UDP address, but an IP address.
Using go-ping
Although the Go net extension library provides icmp packages to facilitate our pinging ability, the code is still a bit on the bottom side of processing. There is a go-ping/ping library on the web that is still used a lot and provides a more advanced or foolproof approach.
Three years on, the impact of the epidemic on the world has been subtle enough to affect the Internet, affecting the open source community. I see a lot of open source projects are no longer maintained for some reason, including this go-ping project, just rely on the author with love can not do lasting, a bit of regret, but at least it has been more mature, we use in the project no problem. prometheus community based on this project, maintain a new project: pro-bing.
The examples in its README document have explained its usage well, you can use it to achieve a similar function as the ping tool, if you want to achieve the ping function in large quantities, this library is not suitable.
The following code is a basic function of ping, nothing to say, ping 3 times to get the result.
|
|
If you want to implement ping under Linux, you can be a little more complex.
|
|
As mentioned earlier, processing the returned messages and matching them with the sent requests is a technical point, so how is go-ping implemented? The main thing is the following code.
|
|
First check the body must be *icmp.Echo
type, this is the basic operation. Then check the pkt.ID, this one filters the ICMP echo reply packet which is not from this program.
Here it also adds its own uuid and time stamp of sending in the sent payload.
Here also deal with duplicate packets, uuid+seq identify the same Echo request.
Through these examples, you should understand the underlying implementation of the ping tool, collect them and return to check them when you encounter related problems.
Next, we’ll talk about the implementation of the traceroute tool, which is more complex than ping, but is related to the ICMP protocol.
Ref
https://colobu.com/2023/04/26/write-the-ping-tool-in-Go/