Unable to open a UDP port with nc

On ubuntu, I can open a UDP port:

nc -lu 5555

Then in another terminal window, send a message:

echo "hello" | nc -u localhost 5555

The message is received at the listener side, as expected.

However this doesn't appear to work on MacOS (10.14.5). The listener invocation starts and blocks as expected, and the port appears to be open, according to lsof:

nc      22583 thisuser   3u  IPv4 0x7af131578e7df639      0t0      UDP *:5555

The sending side completes with no error, but the message doesn't appear to be received at the listener side.

If instead I use a TCP listener and connection, everything works as expected. However, when the TCP listener is first opened, there is a popup to the effect of "Allow application nc to open port?" (I forget the exact message - it is not given again).

So I suspect somehow the OS has a security hook into new listeners; asks for permission with TCP, but for some reason neglects to ask permission with UDP and implicitly denies.

How can I get this to work?


Solution 1:

I hooked up tcpdump to see if the sender side is in fact sending datagrams:

$ sudo tcpdump -i lo0 udp port 5555
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on lo0, link-type NULL (BSD loopback), capture size 262144 bytes
13:53:29.964728 IP6 localhost.49781 > localhost.personal-agent: UDP, length 6

Datagrams are sent, but apparently as IPv6 packets. If I force IPv4 operation, then everything works as expected:

$ nc -l -u 5555 &
[1] 25911
$ echo "Hello" | nc -4 -u localhost 5555
Hello

This leaves the question why does nc -lu open an IPv4 port by default whereas nc -u uses IPv6 by default, but my immediate issue is now fixed.