单步执行 TCP/IP 堆栈
Posted
技术标签:
【中文标题】单步执行 TCP/IP 堆栈【英文标题】:Stepping through a TCP/IP stack 【发布时间】:2012-01-28 14:58:56 【问题描述】:我曾担任专有嵌入式操作系统的 QA 工程师。他们构建了自己的ATN stack,并使用调试器逐步完成它是我在网络方面最令人大开眼界的体验。看着堆栈的每一层构建他们的数据包部分是惊人的。然后终于能够看到线路上构建的数据包具有更多意义。
作为一名教育工作者,我想与他人分享这一经验。有谁知道通过 TCP/IP 堆栈的直接方法?理想情况下,我想要一些比调试 *BSD 或 Linux 内核更容易的东西,尽管如果这是唯一的选择,那么这个过程的一些提示和技巧会很好。一个用 C/C++ 编写的可以在 Visual Studio 或 Eclipse 的用户模式下运行的参考堆栈是理想的。
【问题讨论】:
我不认为调试是最好的学习方式。在 TCP/IP 的情况下,仅读取内核源代码和/或使用 Wireshark 之类的工具检查真实数据包似乎会提供更多信息。 @Evgeny Kluev 我完全不同意。查看线路上的流量只是一个复杂过程的结果。就好像你在看一个女人的影子,试图弄清楚她到底有多漂亮。 对。最后(在再次阅读 OP 之后)我明白了你的意思。这可能令人印象深刻。 您用来单步调试 ATN 堆栈的调试器是什么? 恭喜我的朋友。这是世界需要的那种老师。非常鼓舞人心! 【参考方案1】:这一切都取决于您想要关注什么。根据您的问题,您最感兴趣的是跨不同层的数据流(用户空间流 -> 电缆上的电压)。
为此,我建议您使用http://www.csse.uwa.edu.au/cnet/,它是一个完整的网络模拟器。它允许您单步执行堆栈的所有级别。
真实系统在 Layer3、Layer2 和 Layer1(以太网和 CRC 校验片上固件、硬件 MAC)之间总是有明显的区别。您将无法进入操作系统,并且一些实施细节会让学生感到混乱和困惑。对于 Linux,您必须解释内核基础架构才能理解 TCP/IP 堆栈设计。
如果您只对 TCP/IP 部分感兴趣,我建议您使用嵌入式 TCP/IP 堆栈,例如 http://www.sics.se/~adam/lwip/ 。您可以将其合并到一个简单的用户空间程序中并完全构建 TCP/IP 数据包。
请注意,在单步执行 TCP/IP 堆栈时,您无法解决许多网络通信方面的问题。中间还有一个 MAC 芯片,用于管理介质访问、冲突等。在此之下,有一个 PHY 芯片,可以将所有内容转换为电/光信号,甚至还有一个协议可以处理 MAC 和 PHY 之间的通信。此外,您没有看到与排队、并发、操作系统资源分配 ea 相关的所有方面。一张全貌应该包括所有这些方面,这些方面只能在网络模拟器中看到。
【讨论】:
我记得 cnet 在开发/调整 MIT Mesh layer2 协议 Roofnet 时被广泛使用。第 2 层(尤其是无线网络)中发生了很多有趣的事情,你不能只看 TCP/IP。 我成功安装了 cent (这让我很头疼)。但这看起来像我需要的。 也感谢您提供最完整的答案。只是出于好奇,你是如何研究 MAC 和 PHY 芯片的? 我记得一些关于模拟信号的工程课程,它们处理了以太网线上的信令协议。这种处理过的电缆对不同频率的电阻。关于MAC,我有一个课程是关于创建你自己的点对点无线网络协议,这让你对MAC算法设计有很大的了解(等待时间问题,什么时候让对方说话......)。不过,由于此类算法中的所有计时器问题,我不知道有任何方法可以轻松检查。【参考方案2】:我会在虚拟机中运行 Minix 并对其进行调试。非常适合这个。
Minix 是一个带有 TCP/IP 堆栈的完整操作系统,因此您拥有所需的代码。然而,与 Linux/BSD 不同的是,它的根源和设计目标是成为一种教学工具,因此它避开了一定程度的复杂性,以利于清晰。事实上,这是 Linus Torvalds 在开始使用 Linux 时开始尝试的操作系统 :-)
您可以在虚拟机(如 VirtualBox 或 VMware)中运行 minix 并对其进行调试。网站上有说明:http://www.minix3.org/
【讨论】:
+1 是的,听起来 minix2 可能是学习操作系统的最完整资源。在阅读了 90 年代初期的 minix vs linux、Linus vs Tenembam 的帖子后,看到 minix 的建议很有趣。【参考方案3】:我个人使用 DOS 和 SoftICE 学习了 TCP/IP 堆栈(哎呀,泄露了我是个老家伙)。在虚拟机上使用 DOS 并通过 TCP/IP 驱动程序进行调试会简单得多,因为您的目标是了解 TCP/IP 的工作原理。现代操作系统对网络I/O做了很多优化,调试起来并不容易。
http://www.crynwr.com/ 有一堆开源数据包驱动程序。用源代码调试应该会容易一些。
【讨论】:
DOS 的问题是现代 Windows 机器上的大多数 DOS 实现现在都位于操作系统之上,因此网络优化可能仍在底层进行......你只是在命令行。 我想你误解了我的意思。我的意思是,在虚拟机中运行纯 DOS。在 VM 中,调试 DOS 驱动程序。【参考方案4】:这不是您正在寻找的,但我希望这会有所帮助
1995 - TCP/IP 图解,第 2 卷:实施(与 Gary R. Wright 合着)- ISBN 0-201-63354-X
只需并排浏览代码即可。几乎步入经验。史蒂文先生也解释了关键变量。太棒了。注意:代码可能在本书之后发生了变化,但仍然很棒。
【讨论】:
+1 会是一本很棒的教科书,但它并不能真正回答我的问题。【参考方案5】:lwIP project 可能是您要查找的内容,因为它可以是 run without an operating system。
至于调试 Linux 内核,没有很简单但众所周知的方法。使用KGDB。在虚拟机或单独的机器上安装调试版本的 Linux 内核。并将 GDB 远程连接到这台机器。可能您想使用一些 GDB 前端而不是纯文本界面。如果您需要更多有能力的人提供有关内核调试的详细信息,只需在问题中添加“linux”标签即可。
【讨论】:
有趣的项目,但是在嵌入式平台上编写 C 以提高速度/内存效率会产生一些更难以遵循的不正当技巧。 不一定更难。嵌入式应用程序通常具有较少的速度优化和更多的空间优化。这意味着更少的技巧和更短的代码。 在使用 lwIP 之后,我可以告诉你,它比我经历过的大多数其他网络堆栈更容易遵循(并且在许多情况下具有更好的文档!)。我认为这是一个很好的选择。并且也符合“可以在用户空间中运行”的要求! (除其他外,它有一个 UNIX 端口;请查看它的contrib
项目。)根据定义,它是一个 轻量级 堆栈,因此不包括大多数其他网络堆栈所拥有的东西,例如路由,这可能会给您的学生增加一层混乱。【参考方案6】:
我实际上曾经在8051 中写过一小部分 TCP/IP 堆栈,这是一次非常有启发性的经历。
我相信学习某件事的最好方法就是实践。完成任务后,请与其他开发人员一起获取反馈,并将您的实施与其他现有实施进行比较。
我的观点在这里可能有偏见,但我认为在嵌入式平台中执行此操作是最好的方法。您正在尝试做的事情非常低级,而 PC 只会增加问题的复杂性。嵌入式芯片没有操作系统可以妨碍您。除此之外,很高兴看到一个简单的 8051 响应 ping 请求和 telnet 调用。
他们的关键是从小处着手,不要试图一次创建完整的 TCP/IP 堆栈。编写代码先处理 MAC,然后是 IP、Ping、UDP,最后是 TCP。
我不认为研究现有的实现是一个好主意。 TCP/IP 实现往往会因与您的目标无关的代码而变得臃肿。
【讨论】:
+1 我同意这一点。这样做是最好的学习方式,因为您会遇到各种奇怪的错误,并且必须调试代码。【参考方案7】:我在 TCP/IP 行业工作。在 BSD 和变体中,函数 tcp_input() 是探索 TCP 内部结构的理想起点。在这个函数上设置断点并在一个活系统上单步执行它可以提供很多启示。如果这很难,您可以简单地浏览源代码以大致了解它:
http://fxr.watson.org/fxr/source/netinet/tcp_input.c
了解全局需要时间,至少要好几个星期。相当令人振奋。 :-)
【讨论】:
【参考方案8】:您可以在 Linux 或其他操作系统的用户空间中运行 NetBSD IP 堆栈,使用 gdb 或任何查看 http://www.netbsd.org/docs/rump/ 和 https://github.com/anttikantee/buildrump.sh 的内容,然后将其馈送到 tun/tap 设备,以便您可以查看线路上的内容。
【讨论】:
以上是关于单步执行 TCP/IP 堆栈的主要内容,如果未能解决你的问题,请参考以下文章