【问题标题】:Receiving packets from any protocol on a raw linux socket在原始 linux 套接字上接收来自任何协议的数据包
【发布时间】:2013-10-02 22:25:56
【问题描述】:

我想创建一个 IP 隧道。为此,我在客户端用 C# 创建了一个原始套接字并将其绑定到端口 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 标头。例如,如果我尝试打开到127.0.0.1:4999 的 TCP 连接,C# 应用程序会捕获 3 个数据包。我也可以通过这个套接字发送数据包,它会工作得很好。

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

我已经实现了 除了原始 linux 套接字之外的所有东西这是我的问题:如何在 C/C++ for linux 中编写上述 C# 代码?根据raw(7)的说法,如果我只做socket(AF_INET, SOCK_RAW, IPPROTO_RAW),我不会得到TCP或UDP数据包,对吧?

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

【问题讨论】:

  • Berkeley Sockets 将是 C 恕我直言 gnosis.cx/publish/programming/sockets.html 的首选选项,如果您使用 C++,Boost 等库在 Berkeley 周围有更接近您发布的 C# 代码的包装器。
  • @AllanElder 查看我的编辑。

标签: c# c++ linux sockets ip


【解决方案1】:

没有。

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

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

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

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

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

有一个用于 winpcap 的 .NET 包装器,因此您应该也可以将 winpcap 与 C# 一起使用。

【讨论】:

  • 您在谈论协议标识符。但我希望能够在不关心传输层的情况下传输 IP 数据包。
  • 谢谢,但您误解了我的问题。 Windows 部分工作得很好,我只需要 Linux 部分的帮助。
猜你喜欢
  • 1970-01-01
  • 2023-03-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多