Search code examples
c#socketsnetwork-programming.net-coreipv6

How to receive all IPV6 packets from a nework interface with .Net Core?


In my company, we develop a network product, which acts like a sniffer.

In order to capture all IPV4 packets, we follow the next procedure:

  1. create a raw socket (exact code : new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Udp);
  2. bind it to the IPV4 address of the network interface, port 0 (exact code: socket.Bind(new IPEndPoint(address, 0));)
  3. If we're on Windows, set the socket to promiscuous mode (exact code: socket.IOControl(IOControlCode.ReceiveAll, new byte[]{ 1, 0, 0, 0 }, null);

And this is everything we need in order to capture all IPV4 packets from a network interface. the rest is a simple read operation inside a loop. On Windows, the process has to be executed with admin permissions.

Now, we also want to support IPV6. It's supposed to be easy, but we can't come up with a working solution. Even if nothing throws an exception, the socket is still "stuck" on the read operation. nothing is never received there.

In order to capture IPV6 packets, we modify the above procedure just a bit

  1. Create a socket with Socket(AddressFamily.InterNetworkV6, SocketType.Raw, ProtocolType.IPv6) (note: using ProtocolType.Udp doesn't help either)
  2. Bind to a link-local address (example: socket.Bind(new IPEndPoint(IPAddress.Parse("fe80::dd37:936f:d87:b70c"), 0));). Note: adding a scope-id (like fe80::dd37:936f:d87:b70c%9) doesn't help either.
  3. On Windows, set the socket to promiscuous mode just like the IPV4 procedure.

Another things I've tried:

  • setting the socket to dual mode by calling socket.DualMode = true; between (1) and (2).
  • disabling IPV6-only option on the socket by calling socket.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.IPv6Only, false); between (1) and (2).

I test this by opening Chrome - Chrome fires an MDNS packet both for IPV6 and IPV4 for its chrome-cast feature. Wireshark (which uses a kernel driver), sees this packet and displays it correctly. My code doesn't unblock from the read operation.

I use Windows 10 that supports IPV6.

An ideas how to read all IPV6 packets from the network interface like in IPV4? Thanks.


Solution

  • The solution is to use ProtocolType.IP instead of ProtocolType.IPv6.