如何使用 .Net Core 从网络接口接收所有 IPV6 数据包?
How to receive all IPV6 packets from a nework interface with .Net Core?
在我的公司,我们开发了一个网络产品,它就像一个嗅探器。
为了捕获所有 IPV4 数据包,我们遵循以下步骤:
- 创建原始套接字(确切代码:
new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Udp);
- 将其绑定到网络接口的 IPV4 地址,端口 0(确切代码:
socket.Bind(new IPEndPoint(address, 0));
)
- 如果我们在 Windows,将套接字设置为混杂模式(确切代码:
socket.IOControl(IOControlCode.ReceiveAll, new byte[]{ 1, 0, 0, 0 }, null);
这就是我们从网络接口捕获所有 IPV4 数据包所需的一切。其余的是循环内的简单读取操作。在 Windows,该过程必须以管理员权限执行。
现在,我们也想支持IPV6。这应该很容易,但我们无法提出可行的解决方案。即使没有抛出异常,套接字仍然“卡在”读取操作上。那里从来没有收到过任何东西。
为了抓取IPV6数据包,我们稍微修改一下上面的程序
- 使用
Socket(AddressFamily.InterNetworkV6, SocketType.Raw, ProtocolType.IPv6)
创建套接字(注意:使用 ProtocolType.Udp
也无济于事)
- 绑定到 link-本地地址(示例:
socket.Bind(new IPEndPoint(IPAddress.Parse("fe80::dd37:936f:d87:b70c"), 0));
)。注意:添加范围 ID(如 fe80::dd37:936f:d87:b70c%9
)也无济于事。
- 在 Windows 上,将套接字设置为混杂模式,就像 IPV4 过程一样。
我尝试过的其他事情:
- 通过在 (1) 和 (2) 之间调用
socket.DualMode = true;
将套接字设置为双模式。
- 通过在 (1) 和 (2) 之间调用
socket.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.IPv6Only, false);
在套接字上禁用仅 IPV6 选项。
我通过打开 Chrome 来测试这个 - Chrome 为 IPV6 和 IPV4 触发一个 MDNS 数据包,因为它的 chrome-cast 特性。 Wireshark(使用内核驱动程序)看到此数据包并正确显示。我的代码没有解除对读取操作的阻塞。
我用的是支持IPV6的Windows10
关于如何像在 IPV4 中一样从网络接口读取所有 IPV6 数据包的想法?
谢谢。
解决方案是使用 ProtocolType.IP 而不是 ProtocolType.IPv6.
在我的公司,我们开发了一个网络产品,它就像一个嗅探器。
为了捕获所有 IPV4 数据包,我们遵循以下步骤:
- 创建原始套接字(确切代码:
new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Udp);
- 将其绑定到网络接口的 IPV4 地址,端口 0(确切代码:
socket.Bind(new IPEndPoint(address, 0));
) - 如果我们在 Windows,将套接字设置为混杂模式(确切代码:
socket.IOControl(IOControlCode.ReceiveAll, new byte[]{ 1, 0, 0, 0 }, null);
这就是我们从网络接口捕获所有 IPV4 数据包所需的一切。其余的是循环内的简单读取操作。在 Windows,该过程必须以管理员权限执行。
现在,我们也想支持IPV6。这应该很容易,但我们无法提出可行的解决方案。即使没有抛出异常,套接字仍然“卡在”读取操作上。那里从来没有收到过任何东西。
为了抓取IPV6数据包,我们稍微修改一下上面的程序
- 使用
Socket(AddressFamily.InterNetworkV6, SocketType.Raw, ProtocolType.IPv6)
创建套接字(注意:使用ProtocolType.Udp
也无济于事) - 绑定到 link-本地地址(示例:
socket.Bind(new IPEndPoint(IPAddress.Parse("fe80::dd37:936f:d87:b70c"), 0));
)。注意:添加范围 ID(如fe80::dd37:936f:d87:b70c%9
)也无济于事。 - 在 Windows 上,将套接字设置为混杂模式,就像 IPV4 过程一样。
我尝试过的其他事情:
- 通过在 (1) 和 (2) 之间调用
socket.DualMode = true;
将套接字设置为双模式。 - 通过在 (1) 和 (2) 之间调用
socket.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.IPv6Only, false);
在套接字上禁用仅 IPV6 选项。
我通过打开 Chrome 来测试这个 - Chrome 为 IPV6 和 IPV4 触发一个 MDNS 数据包,因为它的 chrome-cast 特性。 Wireshark(使用内核驱动程序)看到此数据包并正确显示。我的代码没有解除对读取操作的阻塞。
我用的是支持IPV6的Windows10
关于如何像在 IPV4 中一样从网络接口读取所有 IPV6 数据包的想法? 谢谢。
解决方案是使用 ProtocolType.IP 而不是 ProtocolType.IPv6.