I want to join an IPv6 multicast group (in this example: "ff15::2a") via C# code.
What Worked
The following Python implementation works perfectly:
import socket
import struct
with socket.socket(socket.AF_INET6, socket.SOCK_DGRAM) as s:
# Build the request bytes (multicast address + interface [0])
address_bytes = socket.inet_pton(socket.AF_INET6, "ff15::2a")
interface_id = struct.pack("@I", 0)
s.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_JOIN_GROUP, address_bytes + interface_id)
And sends the following packet:
What Didn't Work
The following C# implementation sends the wrong packet:
using System;
using System.Net.Sockets;
Socket socket = new Socket(AddressFamily.InterNetworkV6, SocketType.Dgram, ProtocolType.Udp);
//Build the request bytes (multicast address + interface [0])
byte[] addressBytes = IPAddress.Parse("ff15::2a").GetAddressBytes();
byte[] optionValue = new byte[addressBytes.Length + sizeof(int)];
Buffer.BlockCopy(addressBytes, 0, optionValue, 0, addressBytes.Length);
socket.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.AddMembership, optionValue);
Notice - changed to EXCLUDE!
Remarks
SocketOptionName.DropMembership
sends the opposite packet too, but I can't use it as a workaround because it throws an exception if I'm not a member of the group already- C# works fine with IPv4 multicast, but not IPv6
- I tested C# in .NET 6, .NET Core 3.1 and .NET Framework (Mono)
- This alternative implementation has the same issue:
using System;
using System.Net.Sockets;
Socket socket = new Socket(AddressFamily.InterNetworkV6, SocketType.Dgram, ProtocolType.Udp);
IPAddress address = IPAddress.Parse("ff15::2a");
socket.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.AddMembership, new IPv6MulticastOption(address));