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:
There are a few things to note here:
- 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 fromping
. ncat
sets up and immediately closes the connection, so there are two round trips here.- 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. ¯\_(ツ)_/¯