ARP 回复数据包中的源协议地址和目的协议地址是否应该相同?
如有疑问,创建协议的 RFC 通常会给出答案。RFC 826,以太网地址解析协议描述了当主机收到 ARP 请求时会发生什么,包括为什么这样做的基本原理。它说你,“交换硬件和协议字段,将本地硬件和协议地址放在发送者字段中。" 有些人可能会将此解释为您只更改发送方字段,而另一些人可能认为交换意味着交换。这就是您获得这些协议的冲突信息和实现的方式。通常一个成功的 RFC 会出来解释哪个方向是正确的。在这种情况下,ARP 实际上是第 2 层通信,因此目标 IP 地址实际上不是回复中的问题,因为回复是返回到请求层 MAC 地址,并且它不会向上传递堆叠到第 3 层。
顺便说一下,两个设备是否在同一个子网中并不重要,因为 PC 永远不应该为不在其子网中的 IP 地址进行 ARP;它将为配置的网关 IP 地址发送 ARP,而不是不在其子网中的目标 IP 地址。
数据包接收:
当收到地址解析数据包时,接收以太网模块将数据包交给地址解析模块,该模块通过类似于以下的算法。否定条件表示处理结束并丢弃数据包。
?Do I have the hardware type in ar$hrd? Yes: (almost definitely) [optionally check the hardware length ar$hln] ?Do I speak the protocol in ar$pro? Yes: [optionally check the protocol length ar$pln] Merge_flag := false If the pair <protocol type, sender protocol address> is already in my translation table, update the sender hardware address field of the entry with the new information in the packet and set Merge_flag to true. ?Am I the target protocol address? Yes: If Merge_flag is false, add the triplet <protocol type, sender protocol address, sender hardware address> to the translation table. ?Is the opcode ares_op$REQUEST? (NOW look at the opcode!!) Yes: Swap hardware and protocol fields, putting the local hardware and protocol addresses in the sender fields. Set the ar$op field to ares_op$REPLY Send the packet to the (new) target hardware address on the same hardware on which the request was received.
请注意,在查看操作码之前,<protocol type, sender protocol address, sender hardware address> 三元组已合并到表中。这是基于通信是双向的假设;如果 A 有一些理由与 B 交谈,那么 B 可能有一些理由与 A 交谈。 另请注意,如果 <protocol type, sender protocol address> 对已经存在一个条目,那么新的硬件地址将取代旧的一。相关问题为此提供了一些动力。
概括: ar$hrd 和 ar$hln 字段允许将此协议和数据包格式用于非 10Mbit 以太网。对于 10Mbit 以太网,<ar$hrd, ar$hln> 的值为 <1, 6>。对于其他硬件网络,ar$pro 字段可能不再对应于以太网类型字段,但它应该与正在寻求地址解析的协议相关联。
为什么会这样??
绝对不希望定期广播。想象在一个以太网上有 100 个工作站,每个工作站每 10 分钟广播一次地址解析信息(作为一组可能的参数)。这是每 6 秒一个数据包。这几乎是合理的,但有什么用呢?工作站通常不会相互交谈(因此表中有 100 个无用的条目);他们将主要与大型机、文件服务器或网桥交谈,但仅与少数其他工作站交谈(例如,用于交互式对话)。本文中描述的协议根据需要分发信息,并且每次启动机器仅分发一次(可能)。
这种格式不允许在同一个数据包中进行多个解析。这是为了简单起见。如果事情被多路复用,数据包格式将很难消化,而且大部分信息可能是无偿的。想象一个桥接四个协议,告诉工作站所有四个协议地址,工作站可能永远不会使用其中三个。
这种格式允许在生成回复时重新使用数据包缓冲区;回复的长度与请求的长度相同,并且有几个字段是相同的。
为此,硬件字段 (ar$hrd) 的值取自一个列表。目前唯一定义的值是针对 10Mbit 以太网 (ares_hrd$Ethernet = 1)。也有关于在分组无线电网络中使用该协议的讨论,这将需要另一个值,就像其他希望使用该协议的未来硬件介质一样。
对于 10Mbit 以太网,协议字段 (ar$pro) 中的值取自 ether_type$ 集。这是分配的协议类型的自然重用。将其与操作码 (ar$op) 结合使用将有效地将可在此协议下解析的协议数量减半,并使监视器/调试器更加复杂(请参阅下面的网络监视和调试)。希望我们永远不会看到 32768 协议,但是 Murphy 制定了一些不允许我们做出这种假设的法律。
理论上,长度字段(ar$hln 和 ar$pln)是多余的,因为协议地址的长度应该由硬件类型(在 ar$hrd 中找到)和协议类型(在 ar$pro 中找到)决定. 它用于可选的一致性检查,以及网络监控和调试(见下文)。
操作码是为了确定这是一个请求(可能导致回复)还是对之前请求的回复。16 位用于这个是矫枉过正的,但需要一个标志(字段)。
发送方硬件地址和发送方协议地址是绝对必要的。将这些字段放入转换表中。
目标协议地址在数据包的请求形式中是必需的,以便机器可以确定是否将发送者信息输入表中或发送回复。如果假设回复仅由请求引起,则回复表单中不一定需要它。包含它是为了完整性、网络监控和简化上述建议的处理算法(在将发送者信息放入表中后才查看操作码)。
包含目标硬件地址是为了完整性和网络监控。它在请求表中没有意义,因为机器请求的正是这个数字。它在回复表单中的含义是发出请求的机器的地址。在某些实现中(例如,不会查看 14.byte 以太网标头),这可以通过将此字段作为数据包的硬件目标地址发送到硬件驱动程序来节省一些寄存器混洗或堆栈空间。
地址之间没有填充字节。数据包数据应被视为一个字节流,其中只有 3 个字节对被定义为字(ar$hrd、ar$pro 和 ar$op),它们首先发送最高有效字节(以太网/PDP-10 字节样式) .
我非常同意 Maupin 先生的回答——如有疑问,请咨询适当的 RFC——但一个补充的观点是:当你读到一些听起来很奇怪的关于网络的东西时,自己尝试一下并调查一些设备。
在我实施 ARP 之后,我从未想过有人会误读该ar$tpa
领域。它的定义是绝对明确的:“(ar$tpa) 目标的协议地址”[从上下文隐含的这个数据包]。
我调查了我所有容易获得的设备,并且在每个 ARP 回复的第二个插槽中都没有失败地都有询问者的 IP 地址。(Windows、Linux、HP、Cisco、各种联网设备。)
这里最简单的解释几乎肯定是正确的:教科书是错误的:很可能只是一个简单的错字。为什么不写信给作者,看看你得到什么答复?