Ping: Not Just for Soviet Submarine Captains Anymore!

by Gemma Anible on

It's also for American submarine captains!

We've already talked about how to use traceroute to trace the path information takes through the internet between you and some other computer. What if you're less interested in the route, and more interested in the speed or reliability? Enter ping!

Really, everything in this clip also applies to ping. Except the part where he only wants one. Nobody does that. Unless they're communicating with a spy. #spoilers

I used the same pair of servers as the other post, so I'm running ping on our London server and querying our Lima server.

PING lima.wonderproxy.com (190.12.87.26) 56(84) bytes of data.  
64 bytes from 190.12.87.26: icmp_seq=1 ttl=46 time=175 ms  
64 bytes from 190.12.87.26: icmp_seq=2 ttl=46 time=175 ms  
64 bytes from 190.12.87.26: icmp_seq=3 ttl=46 time=176 ms  
64 bytes from 190.12.87.26: icmp_seq=4 ttl=46 time=175 ms  
64 bytes from 190.12.87.26: icmp_seq=5 ttl=46 time=175 ms  
64 bytes from 190.12.87.26: icmp_seq=6 ttl=46 time=176 ms  
64 bytes from 190.12.87.26: icmp_seq=7 ttl=46 time=175 ms  
64 bytes from 190.12.87.26: icmp_seq=8 ttl=46 time=175 ms  
64 bytes from 190.12.87.26: icmp_seq=9 ttl=46 time=175 ms  
64 bytes from 190.12.87.26: icmp_seq=10 ttl=46 time=175 ms

--- lima.wonderproxy.com ping statistics ---
10 packets transmitted, 10 received, 0% packet loss, time 9008ms  
rtt min/avg/max/mdev = 175.050/175.404/176.084/0.691 ms  

This first line is a lot like traceroute's first line:

PING lima.wonderproxy.com (190.12.87.26) 56(84) bytes of data.  

ping is giving us a summary of my request. (Imagine Vasily repeating his captain's instruction: One ping to the American sub, aye.) My target is lima.wonderproxy.com, which has an IP address of 190.12.87.26. My "message" is a lot like the traceroute message: an information packet that contains 56(84) bytes of dummy data--wait what? 56(84) bytes? To the man(ual) page!

An IP header without options is 20 bytes. An ICMP ECHO_REQUEST packet contains an additional 8 bytes worth of ICMP header followed by an arbitrary amount of data. When a packetsize is given, this indicated the size of this extra piece of data (the default is 56).

We're working with two different kinds of packets here: IP packets and ICMP packets. The IP packet is the big, generic, I'm sending information over the internet! packet that is the great-grandmamma of communication online. Virtually anything and everything you send online gets wrapped in an IP packet. IP packets have 20 bytes dedicated to header information (metadata, like the From: and To: fields in an email), followed by whatever message you're sending. That message is the payload.

The IP payload is a standardized "bucket" for other kinds (protocols) of packets. Part of the IP header is a field that identifies what protocol the IP payload is carrying. In ping's case, the IP payload is an ICMP packet. ICMP packets have their own headers (8 bytes), and their own payloads.

The ICMP payload is the part that ping lets us customize a little. Since we didn't set a specific payload size, our ICMP ping request is using the default of 56 bytes. With the payload size, we know exactly how the IP packet is structured:

  • IP packet: 84 bytes
    • IP header: 20 bytes
    • IP payload (ICMP packet): 64 bytes
      • ICMP header: 8 bytes
      • ICMP payload: 56 bytes

We're pinging lima.wonderproxy.com with 84 bytes of data, 56 bytes of which is meaningless and 28 bytes of which is message headers. It's like we're sending an email that has a To: and a From:, a subject of Please reply!, and 56 spaces in the body.

Unlike an email, ping packets force a reply from their recipients. Part of the 8-byte ICMP header is a section that identifies the type of ICMP message. The ICMP ECHO_REQUEST message that ping sends automatically triggers an ECHO_REPLY message from the target (unless replies have been specifically disabled on purpose), just like a sonar ping bouncing back from a submarine. That's why ping is so useful for figuring out if a server is up. If it's up, it'll reply. Those replies looks like this:

64 bytes from 190.12.87.26: icmp_seq=1 ttl=46 time=175 ms  

(I'm going to skip around in this line a little.)

ttl=46  

You might remember ttl from traceroute: It's the reply packet's time to live, or the number of hosts I can travel through before I expire. In this case, Lima's reply could travel through another 46 hosts if it needed to.

time=175 ms  

The time listed is also a lot like the one from traceroute: It's the round-trip time for the packet, or how long it took to leave London, talk to Lima, and reply back to London. The value has a lot to do with how far apart these two servers are. London, England is over 10,000km from Lima, Peru, so that packet traveled over 20,000km in 175ms. That's a little under half the speed of light. Not bad. It gets even more impressive when you consider that the packet is following network cabling that usually gets routed through major population centers, so really it's even farther.

icmp_seq=1  

This icmp_seq field goes back to that ICMP header from before. Part of the header is the "sequence number," and it lets ECHO_REPLY packets sync up with their associated ECHO_REQUEST packets. Usually, if both your ping target and the network between you and it are healthy, you'll see the icmp_seq value start at 1 and increase by one with each line. If you see those values start jumping around or skipping, there could be something wrong with the server (or the network).

64 bytes  

Remember the bit about payloads and headers from before? We used the default ICMP payload size of 56 bytes with 28 bytes of headers glued on top, for a total packet size of 84 bytes. Why is this line missing 20 bytes?

The reply lines are little different from the introductory line: They show the size of the IP packet's payload, not the total size of the IP packet. Our IP packet's payload is an embedded ICMP packet, which has 56 bytes of dummy data and 8 bytes of ICMP headers. 64 bytes total. If I made the same request with a 2-byte ICMP payload, the ICMP packet would be 10 bytes, and the IP packet would be 30 bytes.

64 bytes from 190.12.87.26: icmp_seq=2 ttl=46 time=175 ms  
64 bytes from 190.12.87.26: icmp_seq=3 ttl=46 time=176 ms  
64 bytes from 190.12.87.26: icmp_seq=4 ttl=46 time=175 ms  
64 bytes from 190.12.87.26: icmp_seq=5 ttl=46 time=175 ms  
64 bytes from 190.12.87.26: icmp_seq=6 ttl=46 time=176 ms  
64 bytes from 190.12.87.26: icmp_seq=7 ttl=46 time=175 ms  
64 bytes from 190.12.87.26: icmp_seq=8 ttl=46 time=175 ms  
64 bytes from 190.12.87.26: icmp_seq=9 ttl=46 time=175 ms  
64 bytes from 190.12.87.26: icmp_seq=10 ttl=46 time=175 ms  

The remaining 9 lines of ECHO_REPLY output look pretty much the same. The time waffles between 175 and 176 ms, and the rest is identical. Why 10 lines total? Because the exact command I ran was

$ ping -c 10 lima.wonderproxy.com

If you run ping without arguments, it will send pings until you tell it to stop. The -c 10 tells ping I want 10 pings only, please.

--- lima.wonderproxy.com ping statistics ---
10 packets transmitted, 10 received, 0% packet loss, time 9008ms  
rtt min/avg/max/mdev = 175.050/175.404/176.084/0.691 ms  

When ping stops running, either because it sent as many packets as you asked it to or because you stopped it yourself, it prints a summary of its experience. It might seem redundant, but remember this thing can run for hours (not that I know from experience because I've accidentally left ping running against non-responsive servers, or anything). When there are thousands of requests and responses, you can't just eyeball the raw output and see that everything's hunky dory.

10 packets transmitted, 10 received, 0% packet loss, time 9008ms  

We sent 10 requests (exactly what I asked for), and we received 10 replies. Every request received a reply, so there were no lost packets, or packets we sent out that never made it back. That's the 0% packet loss bit. If only 9 replies had been received, the packet loss would have been 1 packet out of 10, or 10%.

The total time for this run was about 9 seconds, which is 10 requests with one second between each. The one-second delay is another ping default. We could make it wait longer or shorter with the -i command-line option, but usually one second is fine.

rtt min/avg/max/mdev = 175.050/175.404/176.084/0.691 ms  

rtt here means round-trip time, how long it took for packets to leave and circle back. ping has helpfully calculated some timing statistics for us, listing out the fastest time (175.05 ms), the slowest (176.084 ms), the average (175.404 ms), and the standard deviation (an average of how much each packet's timing varied, or 0.691 ms).

ping has been part of the Where's It Up toolkit for years, and we're building a pretty interface for it for the first time in Observ.io. We're trying to highlight the important information, while simultaneously avoid overwhelming the interface with numbers.

With Observ.io, you can run your own ping tests between London and Lima! Sadly, we haven't worked out how to ping the Red October.