c++ - 发送任意(原始)数据包

标签 c++ networking windows-7 packets

我在别处看到有人问过它,但没有人回答我满意:我如何接收和发送原始数据包?

通过“原始数据包”,我的意思是我必须在何处生成所有 header 和数据,以便字节是完全任意的,并且不受任何限制。这就是 Microsoft 的 RAW 套接字不起作用的原因,因为您无法使用不正确的源地址发送 TCP 或 UDP 数据包。

我知道您可以像使用 WinPCAP 一样发送数据包,但您无法使用它接收原始信息,我也需要这样做。

最佳答案

首先决定你想在哪个协议(protocol)层上测试格式错误的数据:

以太网

如果你想用错误的以太网校验和生成和接收无效的以太网帧,你或多或少不走运,因为校验和通常是在硬件中完成的,在它们不是的情况下,网卡的驱动程序执行校验和至少在 Windows 上没有办法解决这个问题。 NetBSD 为大多数在操作系统驱动程序中进行以太网校验和的驱动程序提供了该选项。

另一种方法是购买专门的硬件(例如 Napatech 的卡,但您可能会找到更便宜的卡),它提供了一个 API,用于发送和接收以太网帧,无论您希望它无效。

请注意,通过发送无效的以太网帧发送,接收端或中间的路由器只会将帧扔掉,它们永远不会到达应用程序或操作系统 IP 层。您将在接收端测试 NIC 或 NIC 驱动程序。

知识产权

如果您只想发送/接收无效的 IP 数据包,winpcap 可以让您做到这一点。生成数据包,设置winpcap抓包,使用winpcap发送..

请注意,具有无效 IP 校验和其他无效字段的数据包,接收应用程序运行的 TCP/IP 堆栈只会将 IP 数据包丢弃,就像发送方和接收方之间的任何 IP/第 3 层路由器一样。他们不会到达应用程序。如果您正在生成有效的 IP 数据包,您还需要生成有效的 UDP 并自己使用有效的 TCP 数据包实现 TCP session ,以便应用程序处理它们,否则它们也会被 TCP/IP 丢弃堆

您将在接收端测试 TCP/IP 堆栈的较低部分。

TCP/UDP

这与发送/接收无效 IP 数据包没有什么不同。你可以用 winpcap 做这一切,尽管路由器不会把它们扔掉,只要以太网/IP header 没问题。但是,应用程序不会收到这些数据包,它们会被 TCP/IP 堆栈丢弃。
您将在接收端测试 TCP/IP 堆栈的上部。

应用层

这是实际测试应用程序的(理智)方式(除非您的“应用程序”实际上是 TCP/IP 堆栈或更低)。您可以像使用套接字的任何应用程序一样发送/接收数据,但会根据需要生成格式错误的应用程序数据。应用程序将接收这些数据,它不会被较低的协议(protocol)层丢弃。

尽管使用 TCP 的一种特定形式的测试可能很难测试 - 即改变发送的 TCP 段,如果您例如想要测试应用程序是否正确地将 TCP 数据解释为流。 (例如,您希望将字符串“hello”分成 5 段发送,并以某种方式使接收应用程序一个一个地 read() 字符)。如果您不需要速度,通常可以通过在发送中插入暂停并关闭 nagel 算法 (TCP_NDELAY) 和/或调整 NIC MTU 来获得该行为。

请记住,TCP 流中具有较低级别协议(protocol)的任何困惑,例如导致其中一个具有无效/不同 IP 源地址的数据包被较低级别的层丢弃。

您将测试运行在 TCP/UDP(或任何其他 IP 协议(protocol))之上的应用程序。

替代品

  • 切换到另一个操作系统,在那里您至少可以使用原始套接字而不受最近窗口的限制。
  • 实现基于上述“以太网”或“IP”替代方案的透明插入式解决方案。即您有普通的客户端应用程序,普通的服务器应用程序。您断开它们之间的电缆,插入带有 2 个 NIC 的盒子,您可以在其中以编程方式更改接收到的帧的字节,然后在另一个 NIC 上再次将它们发送回去。这也将允许您轻松地在系统中引入数据包延迟。 Linux 的 netfilter 已经具有这种功能,您可以在其上轻松构建,通常只需配置或脚本。
  • 如果您可以更改要测试的接收应用程序,请让它从其他内容(例如文件或管道)读取数据,并根据需要向其提供随机字节/数据包。
  • 混合模型,主要用于 TCP 应用程序测试,但也适用于例如测试 UDP ICMP 响应。使用套接字建立 TCP 连接。使用套接字发送无效的应用程序数据。引入随机格式错误的数据包(比使用原始套接字编程更容易,这些套接字设置 TCP session 然后引入低层错误)。使用 WinPcap 发送格式错误的 IP 或 UDP/TCP 数据包,或者可能是 ICMP 数据包,尽管与套接字代码通信到 winpcap 代码,以便地址/端口正确,以便接收应用程序看到它。
  • 退房 NS/2
  • 关于c++ - 发送任意(原始)数据包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6389253/

    相关文章:

    networking - float IP 在 Digital Ocean 上的使用

    c++ - 是否有用于 C++ 短路的 gcc 扩展?

    c++ - 为什么我可以获取字符串文字的地址,而不是整数文字的地址?

    c# - 连续发送鼠标位置到另一台机器

    java - 在 Google Android 中以编程方式连接到 WiFi?

    performance - MPI 应用程序中的 CPU 使用百分比

    c++ - 处理 float 的精度问题

    c++ - AVL树奇怪的行为

    delphi - 为什么 Windows 7 上的 FindFirstFile/FindNextFile 没有列出系统目录的全部内容?

    python - 如何在 Windows 64 上安装 NumPy?