I have a linux network interface that IPv6 multicast traffic is arriving on. There are both ICMPv6 packets and UDP packets arriving for the same multicast group.
I'm trying to receive the UDP traffic. The code below is in Python but I don't believe this is important; the Python library here is a pretty thin wrapper around the BSD sockets API. This is what I'm doing:
import socket
import struct
import select
import ipaddress
# .packet is a byte array
mcast_group = ipaddress.IPv6Address("ff22:5eea:675c:d1fc:17c::1").packed
address = ipaddress.IPv6Address("...ipv6 global scope address of interface...")
sock = socket.socket(socket.AF_INET6, socket.SOCK_RAW, socket.IPPROTO_UDP)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
group = struct.pack("16s i",
mcast_group,
3 #Interface ID
)
sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_JOIN_GROUP, group)
sock.bind((address.compressed, 0, 0, 0))
recv_socks, _, _ = select.select([sock], [], [], 10)
if recv_socks:
print("Received packet")
With the code above, I appear to be receiving both the UDP and ICMPv6 packets. If I change the second parameter to socket.socket()
from socket.SOCK_RAW
to socket.SOCK_DGRAM
then I receive no packets at all.
I've confirmed that both packet types are arriving on that interface, addressed to that multicast group, using wireshark.
There is something here that I've fundamentally not understood about socket()
. Shouldn't specifying IPPROTO_UDP
mean that I only get UDP packets? Shouldn't specifying SOCK_DGRAM
still allow UDP packets through?
The Linux kernel is 4.9 on aarch64, in case that's important.