netcat sending extra "X" UDP packets
Asked Answered
M

3

14

Stealing from here I have set up a small Python script which listens on a port and prints out all of the UDP packets it receives:

import socket

UDP_IP = "127.0.0.1"
UDP_PORT = 5005

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind((UDP_IP, UDP_PORT))

while True:
    data, addr = sock.recvfrom(1024)
    print "received message:", repr(data)

Now I am using netcat to send data to this script. Here is my command line.

echo -e "foo:1|c" | netcat -v -u localhost 5005

And here is the output from Python:

received message: 'X'
received message: 'X'
received message: 'X'
received message: 'X'
received message: 'X'
received message: 'foo:1|c\n'

These first four or so "X" lines arrive at roughly one-second intervals, then the final two lines arrive roughly simultaneously.

My question is this: where are these extra "X" packets coming from, and if the source is netcat, then how can I prevent netcat from emitting them? This is BSD's netcat, I believe.

Megmega answered 18/2, 2016 at 15:34 Comment(0)
B
12

This is BSD's netcat, I believe.

I had the same issue, and when I did nc --version I indeed saw:

This is nc from the netcat-openbsd package. An alternative nc is available in the netcat-traditional package.

Conventional wisdom is that the BSD is the "better" version (see What are the differences between netcat-traditional and netcat-openbsd?)

But anyway, the BSD sources is where one would have to look to find the relevant code for where the "X" is actually coming from. And you don't have to look too hard!

http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/nc/netcat.c?rev=1.177

The smoking gun is a function udptest():

/*
 * udptest()
 * Do a few writes to see if the UDP port is there.
 * Fails once PF state table is full.
 */
int
udptest(int s)
{
    int i, ret;

    for (i = 0; i <= 3; i++) {
        if (write(s, "X", 1) == 1)
            ret = 1;
        else
            ret = -1;
    }
    return (ret);
}

And the conditions under which this is called is if vflag (Verbosity) or zflag (Port Scan Flag) are set:

if (vflag || zflag) {
    /* For UDP, make sure we are connected. */
    if (uflag) {
        if (udptest(s) == -1) {
            ret = 1;
            continue;
        }
    }
    ...

Regarding the rationale for why the -v switch would start throwing random data at the UDP port, I'd guess the idea is that those who are using -v want every bit of information they can get. So the tradeoff of getting an early and vocal error message about the connection is worth it to help someone in a debugging situation.

But even so, my opinion would be that instead of sending the cryptic "X" that sending something like "NETCAT UDP PING DUE TO -V OPTION" would be better. :-/

Billibilliard answered 15/2, 2017 at 5:42 Comment(0)
H
4

For reasons I cannot determine, those X packets are being sent by the -v option to nc. Try this instead:

echo -e "foo:1|c" | netcat -u localhost 5005
Hundley answered 18/2, 2016 at 16:6 Comment(3)
The documentation just says that -v "give[s] more verbose output". Do you think this could be a defect in netcat?Megmega
"For reasons that I cannot determine" was my way of saying, "I don't know why." I don't know if this is a defect in netcat or a designed feature of netcat, or an implementation detail.Timorous
@Hundley The benefit of open source is that one can know...Billibilliard
B
0

Use echo -n "foo:1|c" > /dev/udp/localhost/5005

Bahamas answered 18/2, 2016 at 15:47 Comment(3)
On what OS does /dev/udp exist?Timorous
Ah, I see that is a bash feature, not an OS feature. I didn't know about that.Timorous
I wrote a /dev/udp on QNX long ago. I am pretty sure there was something like that on plan 9 although it worked differently from what I vaguely remember.Unroot

© 2022 - 2024 — McMap. All rights reserved.