c# - 在原始 Linux 套接字上接收来自任何协议(protocol)的数据包

标签 c# c++ linux sockets ip

我想创建一个 IP 隧道。为此,我在客户端上用 C# 创建一个原始套接字并将其绑定(bind)到端口 4999:

Socket mysock = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.IP);
mysock.Bind(new IPEndPoint(IPAddress.Loopback, 4999));
mysock.Connect(new IPEndPoint(IPAddress.Loopback, 4999));

现在我只需调用 mysock.Receive(byte[]),即可获取所有 IP 数据包,包括 IP header 。例如,如果我尝试打开到 127.0.0.1:4999 的 TCP 连接,C# 应用程序会捕获 3 个数据包。我还可以通过这个套接字发送数据包,它会工作得很好。

然后,C# 应用程序将这些数据包传输到在 Linux 计算机上运行的 C++ 应用程序。在那里,我更改发送方端口(这是简单的部分,只需将其写入 TCP header ),然后我想简单地将其发送出去并为我完成其他所有操作,就像在 C# 中一样。显然,我还想从原始 Linux 套接字接收数据包,这样我就可以将它们传输回 C# 应用程序并进行一些通信。

我已经实现了除原始 Linux 套接字之外的所有内容。 这就是我的问题:如何在 Linux 上用 C/C++ 编写上述 C# 代码?根据raw(7) ,如果我只执行 socket(AF_INET, SOCK_RAW, IPPROTO_RAW),我不会收到 TCP 或 UDP 数据包,对吧?

编辑:顺便说一句,我在 Windows 上运行 C# 代码,但这不是我的问题。

最佳答案

没有。

在这种情况下,端口号不应是 TCP 或 UDP 端口号。

它应该是(我不确定)更高级别的协议(protocol)标识符(例如“端口号”6 表示:TCP 数据包,而 17 表示:UDP 数据包)。当前的 Linux 版本规定原始套接字的端口号必须为 0。该应用程序需要“root”权限。

Windows 中的差异(与 Linux 相比):

Windows 文档说原始套接字允许用于 ICMP 和 IGMP 数据包(仅)。

使用 winpcap 库应该允许程序获得对以太网卡的原始访问权限。不过,在这种情况下,您还会看到 14 字节以太网 header (IP header 之前),并且您将收到各种以太网数据包(在正常的 TCP/IP 网络中,这些数据包应该是 ARP、IPv4、IPv6 和 STP),而不仅仅是 IPv4 数据包。

winpcap 有一个 .NET 包装器,因此您也应该能够在 C# 中使用 winpcap。

关于c# - 在原始 Linux 套接字上接收来自任何协议(protocol)的数据包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19036931/

相关文章:

c# - 为什么会有 Nullable<T> 结构和 Nullable 类?

c# - 在 C# 中解码西里尔文 HTML 实体

c# - 当 HttpModule Init 方法在 ASP.NET 集成模式下运行时?

c++ - 特征:逐行计算矩阵范数,比在 vector 上迭代计算它们慢

c - linux内核bpf C代码数组中的省略号

linux - exec 命令被卡住

c# - asp.net-mvc(2) 中 Modelbinding double 的 CultureInfo 问题

python - 带有来自 boost 预处理器的预处理器宏的 SWIG

c++ - 将缓冲区从 C++ 模块返回到 node.js

c sendto函数在linux2.6.29中设置 “network is unreachable” errno