0

I'm trying to send a binary packet to a local process, via netcat (nc), like this:

nc -w 1 -u localhost 10000 < my_binary_packet.bin

The output is:

read(net): Connection refused

Anyone know what's going on?

I get the same result with nc -w 1 -u 127.0.0.1 10000 < my_binary_packet.bin

5
  • 2
    Try reading this ... Jun 18, 2022 at 6:26
  • Before thinking you have a network issue, check that your process is actually running and actually opened a socket to receive traffic (strace can help but on embedded it would be more difficult. That's why there are developer board versions too).
    – A.B
    Jun 18, 2022 at 10:28
  • Note that Connection refused is really relevant to TCP connections. UDP is connectionless, so you typically don't get that even if nothing is listening.
    – user10489
    Jun 18, 2022 at 12:15
  • 1
    @user10489 not really. nothing on an UDP destination port triggers an ICMP destination port unreachable which is translated by ECONNREFUSED (connection refused) on the UDP socket receiving this ICMP back. There is not an infinite quantity of values and thus no "UDP packet refused error". A firewall rule could also generate this ICMP though.
    – A.B
    Jun 18, 2022 at 15:16
  • 1
    @user10489 You can test it easily with OP's method but not with netcat, because there are multiple implementations of netcat and we never know which one was used. try this to test it reliably: echo foo | socat udp:localhost:10000 - .
    – A.B
    Jun 18, 2022 at 15:21

1 Answer 1

1

Summary

If your listener is bound to a particular IP (such as 192.168.0.10) and port (such as 10000) instead of to IP INADDR_ANY (Internet Namespace Address Any, which means it listens to all interfaces / IP addresses), do this instead to specify the correct IP:

# with netcat
nc -w 1 -u 192.168.0.10 10000 < my_binary_packet.bin

# OR (same thing), with socat
socat udp:192.168.0.10:10000 - < my_binary_packet.bin

Details

Ok so I figured it out!

I wrote the local listener process (UDP "server/listener") I was trying to send the binary packet to (from a UDP "client/sender"), and I had bound that socket to a particular IP address, 192.168.0.10, instead of to the "catch-all" IP address INADDR_ANY. Binding to that particular IP address means that my listener process is NOT listening to localhost (127.0.0.1), so those packets were getting rejected! I didn't know that you could send a process running on the same PC some data by using anything other than localhost or 127.0.0.1, but apparently you can.

So, this works instead:

nc -w 1 -u 192.168.0.10 10000 < my_binary_packet.bin

The timeout/wait period of 1 second (-w 1), however, doesn't seem to do anything--I'm not sure why. It just sits there after it sends the packet, and I have to Ctrl + C the nc process after it sends, if I want to send it again. That doesn't really matter though--the point is: it works!

I also carefully read the comments under my question, so here's some more information for anyone wondering:

The equivalent socat command is this (don't forget the - in the command!):

socat udp:192.168.0.10:10000 - < my_binary_packet.bin

Also, here are my versions of netcat and socat on the embedded Linux board.

# nc -h
GNU netcat 0.7.1, a rewrite of the famous networking tool.

# nc -V
netcat (The GNU Netcat) 0.7.1
Copyright (C) 2002 - 2003  Giovanni Giacobbi

# socat -V
socat by Gerhard Rieger and contributors - see www.dest-unreach.org
socat version 1.7.3.4 on May  6 2022 17:55:04

Going further

How to build a binary packet in C or C++ to send via netcat or socat

Lastly, for anyone wondering, the way I wrote the binary packet my_binary_packet.bin is by simply writing some C code to write a packed struct to a file using the Linux write() command.

Writing the packet to a binary file like this allows for easy testing via netcat or socat, which is what drove me to ask the question when it didn't work.

Be sure to set file permissions while opening the file. Ex:

int file = open("my_binary_packet.bin", O_WRONLY | O_CREAT, 0644);

And here is what the struct definition looks like. The my_binary_packet.bin file literally just contains a byte-for-byte copy of this struct inside that binary packet, after I set particular, required values for each member of the struct:

struct __attribute__((__packed__)) my_packet {
    bool flag1;
    bool flag2;
    bool flag3;
};

Full code to open the file, create the packet, and write the binary packet to a file might look like this:

typedef struct __attribute__((__packed__)) my_packet_s {
    bool flag1;
    bool flag2;
    bool flag3;
} my_packet_t;
    
int file = open("my_binary_packet.bin", O_WRONLY | O_CREAT, 0644);
if (file == -1)
{
    printf("Failed to open. errno = %i: %s\n", errno, strerror(errno));
    return;
}

my_packet_t my_packet = 
{
    .flag1 = true,
    .flag2 = true,
    .flag3 = true,
};

ssize_t num_bytes_written = write(file, &my_packet, sizeof(my_packet));
if (num_bytes_written == -1)
{
    printf("Failed to write. errno = %i: %s\n", errno, strerror(errno));
    return;
}

int retcode = close(file);
if (retcode == -1)
{
    printf("Failed to close. errno = %i: %s\n", errno, strerror(errno));
    return;
}

For anyone who wants to learn how to program Berkeley sockets in C or C++...

I wrote this really thorough demo in my eRCaGuy_hello_world repo. This server code is what my UDP listener process is based on:

  1. socket__geeksforgeeks_udp_server_GS_edit_GREAT.c
  2. socket__geeksforgeeks_udp_client_GS_edit_GREAT.c

References

  1. The comments under my question.
  2. There are many versions of netcat: Netcat - How to listen on a TCP port using IPv6 address?
  3. This answer, and my comment here: Error receiving in UDP: Connection refused

See also

  1. My answer on General netcat (nc) usage instructions, including setting the IP address to bind to when receiving, or to send to when sending

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .