0

I'm trying to get OpenBSD netcat to listen to UDP connections on a particular port (3333) and interface (10.42.0.1) and send a fixed response. To achieve this I do:

echo "asd" | nc -k -u -l -p 3333 -s 10.42.0.1 -v

And then I send a message by doing:

echo qwe | nc -u 10.42.0.1 3333 -v

The outputs are

# Server side
Bound on h9ct3d3 3333
XXXXXqwe

# Client side
Connection to 10.42.0.1 3333 port [udp/*] succeeded!

As you can see, the client does not receive asd. However, if I remove the -k, it does receive it:

##### Server side
echo "asd" | nc -u -l -p 3333 -s 10.42.0.1 -v
Bound on h9ct3d3 3333
# ...
# Wait for the client to execute
# ...
Connection received on h9ct3d3 51318
XXXXXqwe

##### Client side
echo qwe | nc -u 10.42.0.1 3333 -v
# ...
# Wait for the above 'X'to finish
# ...
Connection to 10.42.0.1 3333 port [udp/*] succeeded!
asd

I have tried to use a while loop without the -k, but nc never returns:

#!/bin/bash

while true
do
    echo "Host message" | nc -q 0 -u -l -p 3333 -s 10.42.0.1 -v
    echo "restarting..."
done

How can I make this work?

My version of netcat is:

OpenBSD netcat (Debian patchlevel 1.206-1ubuntu1)

PD. Why does the nc server 'send' those weird X characters? The client never reads them, it just waits for them to finish. They seem to be displayed every 1 sec.

Dan
  • 145
  • 1
  • 2
  • 6

1 Answers1

1

The server isn't sending the Xs; the client is sending them, at intervals of 1 second after the first two, and the server displays them (as it should). If you take -v off the client, the Xs aren't sent, or displayed, and the data is sent and displayed immediately (not after 3sec). I have no clue why -v means 'send 5 X characters slowly'!

The man page for -k says

When used together with the -u option, the server socket is not connected and it can receive UDP datagrams from multiple hosts.

Consistent with this, server -v logs Connection from {host} {port} received! when using -ul but not when using -ulk. I suspect the code for sending the 'response' data relies on the socket being connected, and thus leaving it not connected prevents the response, but I have not dug through the source to verify.

-q 0 isn't going to work because there is no detectable 'end of connection' in UDP, while there is in TCP (FIN exchange). If there is something recognizable about your client data -- such as head -1 if it is, always, one line -- logically it should be possible to write something that recognizes that data and kills the nc process allowing the loop to iterate, but I haven't been able to work out a clean way to get the pid of the nc available to such a recognizer/killer. Making CW in case anyone else can provide a real solution here.

dave_thompson_085
  • 3,262
  • 1
  • 16
  • 16