I'm using netcat on Fedora to test an IPv6 UDP multi-cast address. The command is

echo hi | nc -6 -u ff02::777:777:777 7777

netcat responds, "Invalid argument."

Running strace yields

connect(3, {sa_family=AF_INET6, sin6_port=htons(7777), sin6_flowinfo=htonl(0), inet_pton(AF_INET6, "ff02::777:777:777", &sin6_addr), sin6_scope_id=0}, 28) = -1 EINVAL

Running a similar command but without the IPv6,

echo hi | nc -u 7777

works just fine.

1 Answer 1


Preliminary note: your IPv4 network is not set up as but most probably as or any other /24 range: is thus not a broadcast, else echo hi | nc -u 7777 would have failed. For broadcast, not supported with IPv6 but only with IPv4, an application must use the SO_BROADCAST socket option. This is achieved with the -b option for netcat. Assuming you are actually in network (not /16), that would be:

nc -b -u 7777

Note that broadcast is not multicast.

About the question. The entire ff02::/16 range is within the link-local multicast scope. For this scope an address is complete only when an interface is associated to it (that's why it's a link-local scope). A valid address in this range can't be only ff02::777:777:777. Assuming that the LAN interface is called eth0,ff02::777:777:777%eth0 is a valid address, as defined in RFC 4007:

nc -6 -u ff02::777:777:777%eth0 7777

This is probably automatically handled by libraries rather than by the nc command itself. Using a scope not requiring an interface will usually fail because then the interface should not be part of the address.

If you don't want to have to need the interface, don't use the link-local (nor node-local) scope(s). Switch to site-local: ff05 which doesn't require specifying an interface to work:

nc -6 -u ff05::777:777:777 7777

On Linux the distinction can be seen for these two commands with ss:

$ ss -aun dport == 7777
State  Recv-Q  Send-Q                     Local Address:Port          Peer Address:Port
ESTAB  0       0           [2001:db8:900d:cafe:0:1:2:3]:58092  [ff05::777:777:777]:7777        
ESTAB  0       0       [fe80::8c5f:87ff:fe50:d08a]%eth0:60937  [ff02::777:777:777]:7777        

Here as a global address is available on eth0 and it's not a link-local scope, this address was chosen as source. For the link-local scoped address, the socket is bound to the interface. For the Linux case, see this Q/A for other caveats related to the choice of the interface when sending (and having not used IPV6_MULTICAST_IF): How to set preferred IPv6 interface

Final note: you should consider switching to socat with much more features than netcat, including joining multicast groups for IPv4. While it supports IPv6 it doesn't directly support IPv6 multicast but can use arbitrary setsockopt(2) calls for unsupported features, including handling IPv6 multicast. That's still better than netcat which just has no support to receive multicast traffic emitted by the previous netcat commands.

So with socat, here's an example valid at least on Linux with amd64 (x86_64) architecture and possibly working on other *nix possibly after changing the value 20 below with its adequate replacement (for IPV6_ADD_MEMBERSHIP/IPV6_JOIN_GROUP), using a raw setsockopt(2) option to enable receiving the multicast traffic on the interface with index 2 (the first interface after lo), sent by the first netcat command:

socat udp6-recv:7777,setsockopt-listen=41:20:xff020000000000000000077707770777i2 -

The option would be decoded like this using strace:

setsockopt(5, SOL_IPV6, IPV6_ADD_MEMBERSHIP, {inet_pton(AF_INET6, "ff02::777:777:777", &ipv6mr_multiaddr), ipv6mr_interface=if_nametoindex("eth0")}, 20) = 0

The so-called "dalan" format for passing arbitrary socket options is used here for an ipv6_mreq structure: one IPv6 address (x for arbitrary hex values, here 16 bytes for the IPv6 address) followed by one interface index (i for an integer).

You must log in to answer this question.

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