4

This is a slightly obscure question, but I'm stumped and I thought maybe somebody out there might have more of a clue on the issue.

My co-worker has been successfully running an in-house application that uses IPv6 multicasting on his MacBook Pro for several months, but today the Mac decided to stop routing the multicast packets. In particular, the program prints this error:

SendDataUDP(ff02::bead:cede:deed:feed@4) failed on Network interface [Name=[en0] Description=[] IP=[fe80::222:41ff:fe21:dfd4@4] Netmask=[ffff:ffff:ffff:ffff::] Broadcast=[::]] (errno=65/No route to host).

... which pretty well describes what went wrong... it tried to sendto() a UDP packet to the IP address shown, and send() failed with errno=EHOSTUNREACH.

What I don't understand is, what could possibly cause an IPv6 link-scope multicast address to be "unreachable"? If my understanding of link-scope multicast is correct, the packet only has to go out the local ethernet port (en0 in this case, which is up and working on that machine).

Is there some aspect to multicasting that I'm missing, or is his machine just borked? He says he didn't change anything, it just mysteriously stopped working.

Jeremy Friesner
  • 70,199
  • 15
  • 131
  • 234

2 Answers2

3

To test whether en0 is still capable of transmitting link-local multicast requests, try

ping6 ff02::1%en0

This contacts all hosts, so you should get plenty of responses (for fun, try adding -w).

Martin v. Löwis
  • 124,830
  • 17
  • 198
  • 235
  • 1
    funny, that didn't work, I had to use the '-I' option to specify ethernet address to ping6. jdks-mbp:~ jeffk$ ping6 ff02::1%en0 ping6: UDP connect: No route to host jdks-mbp:~ jeffk$ ping6 -I en0 ff02::1 PING6(56=40+8+8 bytes) fe80::21f:f3ff:fed8:3680%en0 --> ff02::1 16 bytes from fe80::21f:f3ff:fed8:3680%en0, icmp_seq=0 hlim=64 time=0.131 ms – jdkoftinoff Aug 12 '09 at 16:55
2

It might help to look at the kernel source. (In particular, the egress IPv6 packet egress path, ip6_output.c) While you're in there, you could also take a look at the socket calls leading up to it, etc.

For multicast, assuming you're making it to ip6_output(), it looks like the only possible way to get this error is by not specifying the interface to send on. (which is odd since your error message explicitly mentions the interface)

Is it possible that the wireless interface on this MacBook has been enabled when it wasn't before, and now the idea of a "link-local" multicast is ambiguous? Are you explicitly specifying the interface when you use the socket? The @4 at the end of the address looks odd to me. (Is that an interface index?) The convention is usually to use % for an interface scope-id, but as noted in the previous answer and its comments, it's not universally supported.

mpontillo
  • 13,559
  • 7
  • 62
  • 90
  • 3
    We finally figured out the problem here.... under MacOS/X, at least, it's not enough to put the interface index into the destination address of the sendto() call. The OS can and sometimes does choose its own interface index to use, ignoring the one that is supplied and causing problems. The work-around is to call setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &myIdx, sizeof(myIdx)) on the socket as needed, instead of (or in addition to) specifying the interface index in the sendto() address argument. I'm not sure if that's a bug or a "feature"... – Jeremy Friesner Jan 18 '10 at 01:42
  • @JeremyFriesner Hello from 2022 where this still seems to be an issue. And in Rust I don't have an easy way to setsockopt(...). I'd be curious if you ever answered the bug vs. feature question. – Cody Casterline Feb 20 '22 at 08:30
  • @CodyCasterline I don't have any further info; Apple moves in mysterious ways. Surely there is a way to call setsockopt() from Rust, though... presumably they wouldn't define the constant if there wasn't a way to use it? https://docs.piston.rs/gfx_text/libc/constant.IPV6_MULTICAST_IF.html – Jeremy Friesner Feb 20 '22 at 18:40
  • I did find a way, I just haven't tested it yet: https://docs.rs/socket2/0.4.4/socket2/struct.Socket.html#method.set_multicast_if_v6 – Cody Casterline Feb 20 '22 at 19:27
  • Hah! OK I think setting the multicast_if may have fixed me in the general case, but here's a fun similar issue. I'm writing a utility that does a quick multicast broadcast/listen on each of a computer's networks. I have some en5 interface that continues to return No Route To Host errors. … that's because it's a bridge interface to the MacBook touch bar. Guess I'll just write an exception for that one. ‍♂️ https://stackoverflow.com/questions/50520202/macos-en5-network-cant-be-turned-off – Cody Casterline Feb 20 '22 at 23:15