cadlag dot org

ncat as an alternative ping

Whether it is used for diagnosing connectivity issues or measuring network latency, ping is an essential tool in any software engineer’s toolkit. Under the hood, ping relies on ICMP echo messages. 1

But many network administrators disable ICMP, or at least certain types of ICMP traffic. This is sometimes for security reasons, as ICMP can be used to map out a network, or as part of a denial-of-service attack. So what if you need to ping a host but can’t?

If this host accepts TCP requests, one option is to try to open a TCP connection. A convenient tool for this is ncat, a part of the nmap suite. On macOS, installing this is as simple as brew install nmap.

Let’s do a quick comparison between ncat and ping. To open a TCP connection and immediately close it, we can run ncat -zv google.com 80. The -z is for “zero I/O” mode, and we want -v to see some output. I’m asking for port 80, since I know google.com is serving HTTP requests there. I see the following output:

Ncat: Version 7.95 ( https://nmap.org/ncat )
Ncat: Connected to 142.251.40.46:80.
Ncat: 0 bytes sent, 0 bytes received in 0.09 seconds.

On the other hand, running ping 142.251.40.46 I get

PING 142.251.40.46 (142.251.40.46): 56 data bytes
64 bytes from 142.251.40.46: icmp_seq=0 ttl=116 time=16.572 ms
64 bytes from 142.251.40.46: icmp_seq=1 ttl=116 time=16.137 ms
64 bytes from 142.251.40.46: icmp_seq=2 ttl=116 time=16.583 ms
^C
--- 142.251.40.46 ping statistics ---
3 packets transmitted, 3 packets received, 0.0% packet loss

A key difference is that ncat reports significantly higher latency than ping. How can we explain this?

When I ran the above, I also captured the network traffic with Wireshark. Below is what I see for the ncat call:

ncat packets

There are a few things to note here:

  1. The initial SYN + SYN/ACK round trip (the first part of establishing the TCP connection) has a latency of about 16ms, which is consistent with what we see from ping.
  2. ncat sets up and immediately closes the connection, so there are two round trips here.
  3. Network latency doesn’t fully account for the duration that ncat reports.

I’m not quite sure how to make sense of this 90ms duration when the TCP connection establishment and teardown was less than 40ms. It’s likely that the ncat duration is computed across a few calls to a system timer, and also includes the user/kernel transitions for the underlying socket processing – so some additional latency beyond the network time-of-flight is expected. With that said, I re-ran the same command a few times and saw durations as low as 50ms and as high as 170ms. ¯\_(ツ)_/¯


  1. I have also written about this here↩︎

Reply to this post by email ↪