跳到主要内容

RFC 826 - 以太网地址解析协议

  • 状态: Internet Standard
  • 发布日期: November 1982
  • Stream: Legacy
  • 勘误: 无勘误

以太网地址解析协议 (Ethernet Address Resolution Protocol)

副标题: 将网络协议地址转换为 48 位以太网地址以便在以太网硬件上传输

作者: David C. Plummer (DCP@MIT-MC)
日期: 1982 年 11 月
状态: 标准 (Standard)


摘要 (Abstract)

发送主机 S 上协议 P 的实现通过协议 P 的路由机制决定要向目标主机 T 发送数据, 目标主机 T 位于某条已连接的 10Mbit 以太网电缆上. 为了实际传输以太网数据包, 必须生成一个 48 位以太网地址. 协议 P 中主机的地址并不总是与对应的以太网地址兼容 (长度或值不同). 本文提出了一种协议, 允许动态分发所需信息, 以构建将协议 P 地址空间中的地址 A 转换为 48 位以太网地址的映射表.

本协议已进行了泛化处理, 使其可用于非 10Mbit 以太网硬件. 部分分组无线网络 (Packet Radio Network) 就是此类硬件的示例.


本文所描述的协议是与多位同仁深入讨论的成果, 尤其感谢 J. Noel Chiappa, Yogen Dalal 和 James E. Kulp, 以及 David Moon 提供的宝贵意见.

[本 RFC 的目的是提出一种将协议地址 (如 IP 地址) 转换为本地网络地址 (如以太网地址) 的方法. 这是目前 ARPA Internet 社区普遍关注的问题. 此处提出的方法供参考和评议, 并非 Internet 标准规范.]


说明 (Notes)

本协议最初为 DEC/Intel/Xerox 10Mbit 以太网设计, 后经泛化以适用于其他网络类型. 大部分讨论将针对 10Mbit 以太网展开, 适用时将在以太网专项讨论之后给出泛化说明.

DOD Internet Protocol (国防部互联网协议) 在本文中简称为 Internet.

本文中的数字遵循以太网标准的高字节优先 (High Byte First) 顺序, 与 PDP-11 和 VAX 等机器的字节寻址顺序相反. 因此, 对下文描述的操作码字段 (ar$op) 需特别注意.

目前存在一个权威机构 (见下文) 负责管理硬件名称空间值. 在该机构成立之前, 请求应发送至:

David C. Plummer
Symbolics, Inc.
243 Vassar Street
Cambridge, Massachusetts 02139

也可通过网络邮件发送至 <DCP@MIT-MC>.


问题 (The Problem)

世界总体上是一片丛林, 网络领域更是如此. 在网络架构的几乎每一层都存在多种可用协议. 例如, 在高层有用于远程登录的 TELNET 和 SUPDUP; 在其下方有可靠字节流协议, 可能是 CHAOS 协议, DOD TCP, Xerox BSP 或 DECnet; 更接近硬件的是逻辑传输层, 可能是 CHAOS, DOD Internet, Xerox PUP 或 DECnet. 10Mbit 以太网通过以太网数据包头中的类型字段允许所有这些协议 (及更多) 在同一电缆上共存. 然而, 10Mbit 以太网在物理电缆上需要 48 位地址, 而大多数协议地址并非 48 位长, 也不一定与硬件的 48 位以太网地址有任何关联. 例如, CHAOS 地址为 16 位, DOD Internet 地址为 32 位, Xerox PUP 地址为 8 位. 因此需要一种协议来动态分发 <协议, 地址> 对与 48 位以太网地址之间的对应关系.


动机 (Motivation)

随着越来越多的制造商提供符合 DEC, Intel 和 Xerox 发布规范的接口, 10Mbit 以太网的可用性不断提高. 随着可用性的增加, 越来越多的软件被编写用于这些接口. 有两种选择: (1) 每个实现者自行发明某种地址解析方法, 或 (2) 每个实现者使用统一标准, 使其代码无需修改即可分发到其他系统. 本提案旨在建立该标准.


定义 (Definitions)

为以太网数据包头 TYPE 字段的值定义如下:

  • ether_type$XEROX_PUP
  • ether_type$DOD_INTERNET
  • ether_type$CHAOS

以及一个新值:

  • ether_type$ADDRESS_RESOLUTION

同时定义以下值 (后文将详细讨论):

  • ares_op$REQUEST (= 1, 高字节先发送)
  • ares_op$REPLY (= 2)

以及:

  • ares_hrd$Ethernet (= 1)

数据包格式 (Packet Format)

为了传递 <协议, 地址> 对到 48 位以太网地址的映射, 需要一种体现地址解析协议 (Address Resolution Protocol) 的数据包格式. 格式如下:

以太网传输层 (用户不一定可访问):

48.bits: 以太网目标地址
48.bits: 以太网源地址
16.bits: 协议类型 = ether_type$ADDRESS_RESOLUTION

以太网数据包数据:

16.bits: (ar$hrd) 硬件地址空间 (如 Ethernet, Packet Radio Net.)
16.bits: (ar$pro) 协议地址空间. 对于以太网硬件, 取自 ether_typ$<protocol> 集合
8.bits: (ar$hln) 每个硬件地址的字节长度
8.bits: (ar$pln) 每个协议地址的字节长度
16.bits: (ar$op) 操作码 (ares_op$REQUEST | ares_op$REPLY)
nbytes: (ar$sha) 本数据包发送方的硬件地址, n 来自 ar$hln 字段
mbytes: (ar$spa) 本数据包发送方的协议地址, m 来自 ar$pln 字段
nbytes: (ar$tha) 本数据包目标方的硬件地址 (如已知)
mbytes: (ar$tpa) 目标方的协议地址

数据包生成 (Packet Generation)

当数据包沿网络层向下传送时, 路由机制确定该数据包下一跳的协议地址, 以及期望在哪块硬件上找到具有直接目标协议地址的站点. 对于 10Mbit 以太网, 需要进行地址解析, 某个较低层 (可能是硬件驱动程序) 必须咨询地址解析模块 (可能在以太网支持模块中实现), 将 <协议类型, 目标协议地址> 对转换为 48 位以太网地址. 地址解析模块尝试在表中查找该对. 若找到, 则将对应的 48 位以太网地址返回给调用方 (硬件驱动程序), 由其传输数据包. 若未找到, 则可能通知调用方丢弃该数据包 (假设数据包将由更高网络层重传), 并生成一个类型字段为 ether_type$ADDRESS_RESOLUTION 的以太网数据包. 地址解析模块随后将 ar$hrd 字段设置为 ares_hrd$Ethernet, ar$pro 设置为正在解析的协议类型, ar$hln 设置为 6 (48 位以太网地址的字节数), ar$pln 设置为该协议中地址的长度, ar$op 设置为 ares_op$REQUEST, ar$sha 设置为自身的 48 位以太网地址, ar$spa 设置为自身的协议地址, ar$tpa 设置为试图访问的机器的协议地址. 它不会将 ar$tha 设置为任何特定值, 因为这正是它试图确定的值. 如果对实现的某些方面有便利, 可以将 ar$tha 设置为硬件的广播地址 (10Mbit 以太网中为全 1). 然后将此数据包广播到由路由机制最初确定的以太网电缆上的所有站点.


数据包接收 (Packet Reception)

当收到地址解析数据包时, 接收方以太网模块将数据包交给地址解析模块, 后者执行类似以下的算法. 否定条件表示处理结束并丢弃数据包.

?ar$hrd 中的硬件类型是否为我所支持?
是: (几乎肯定)
[可选: 检查硬件长度 ar$hln]
?ar$pro 中的协议是否为我所支持?
是:
[可选: 检查协议长度 ar$pln]
Merge_flag := false
如果 <协议类型, 发送方协议地址> 对已在我的转换表中,
则用数据包中的新信息更新该条目的发送方硬件地址字段,
并将 Merge_flag 设为 true.
?我是目标协议地址吗?
是:
如果 Merge_flag 为 false, 则将三元组 <协议类型,
发送方协议地址, 发送方硬件地址> 添加到转换表.
?操作码是 ares_op$REQUEST 吗? (现在才查看操作码!!)
是:
交换硬件和协议字段, 将本地硬件和协议地址放入发送方字段.
将 ar$op 字段设置为 ares_op$REPLY
在收到请求的同一硬件上将数据包发送到 (新的) 目标硬件地址.

注意, <协议类型, 发送方协议地址, 发送方硬件地址> 三元组在查看操作码之前就已合并到表中. 这基于通信是双向的假设: 如果 A 有理由与 B 通信, 那么 B 也可能有理由与 A 通信. 还需注意, 如果 <协议类型, 发送方协议地址> 对的条目已存在, 则新硬件地址将取代旧条目. 相关问题章节对此给出了一些说明.

泛化说明: ar$hrdar$hln 字段允许本协议和数据包格式用于非 10Mbit 以太网. 对于 10Mbit 以太网, <ar$hrd, ar$hln> 取值为 <1, 6>. 对于其他硬件网络, ar$pro 字段可能不再对应以太网类型字段, 但应与正在寻求地址解析的协议相关联.


为何如此设计? (Why is it done this way?)

周期性广播显然是不可取的. 设想一条以太网上有 100 台工作站, 每台每 10 分钟广播一次地址解析信息 (作为一组可能的参数). 这相当于每 6 秒一个数据包. 这几乎是合理的, 但有什么用呢? 工作站通常不会相互通信 (因此表中会有 100 个无用条目); 它们主要与主机, 文件服务器或网桥通信, 只与少数其他工作站通信 (例如用于交互式会话). 本文描述的协议按需分发信息, 且每次机器启动可能只需一次.

此格式不允许在同一数据包中完成多个解析. 这是为了简单起见. 如果进行多路复用, 数据包格式将难以解析, 且大量信息可能是多余的. 试想一个使用四种协议的网桥向工作站告知所有四个协议地址, 而工作站可能永远不会使用其中三个.

此格式允许在生成回复时重用数据包缓冲区; 回复与请求长度相同, 且多个字段相同.

硬件字段 (ar$hrd) 的值取自专用列表. 目前唯一定义的值是 10Mbit 以太网 (ares_hrd$Ethernet = 1). 已有讨论将此协议用于分组无线网络 (Packet Radio Network), 这将需要另一个值, 未来希望使用此协议的其他硬件介质也同样如此.

对于 10Mbit 以太网, 协议字段 (ar$pro) 的值取自 ether_type$ 集合. 这是对已分配协议类型的自然复用. 将其与操作码 (ar$op) 合并将有效地将此协议下可解析的协议数量减半, 并使监控/调试器更加复杂 (见下文网络监控与调试). 希望我们永远不会看到 32768 种协议, 但墨菲定律告诉我们不能做此假设.

理论上, 长度字段 (ar$hlnar$pln) 是冗余的, 因为协议地址的长度应由硬件类型 (ar$hrd) 和协议类型 (ar$pro) 确定. 包含它们是为了可选的一致性检查以及网络监控和调试 (见下文).

操作码用于确定这是一个请求 (可能引发回复) 还是对先前请求的回复. 16 位对此来说过于充裕, 但确实需要一个标志 (字段).

发送方硬件地址和发送方协议地址是绝对必要的. 正是这些字段被放入转换表.

目标协议地址在请求形式的数据包中是必要的, 以便机器确定是否将发送方信息录入表中或发送回复. 如果假设回复仅由请求触发, 则在回复形式中不一定需要. 包含它是为了完整性, 网络监控, 以及简化上述建议的处理算法 (该算法在将发送方信息放入表之后才查看操作码).

目标硬件地址包含在内是为了完整性和网络监控. 它在请求形式中没有意义, 因为这正是机器正在请求的数字. 它在回复形式中的含义是发出请求的机器的地址. 在某些实现中 (例如无法访问 14 字节以太网头的实现), 通过将此字段作为数据包的硬件目标地址发送给硬件驱动程序, 可以节省一些寄存器操作或栈空间.

地址之间没有填充字节. 数据包数据应视为字节流, 其中只有 3 个字节对被定义为字 (ar$hrd, ar$proar$op), 以最高有效字节优先 (Ethernet/PDP-10 字节风格) 发送.


网络监控与调试 (Network Monitoring and Debugging)

上述地址解析协议允许机器获取以太网电缆上高层协议活动 (如 CHAOS, Internet, PUP, DECnet) 的相关信息. 它可以确定哪些以太网协议类型字段正在使用 (按值), 以及每种协议类型内的协议地址. 事实上, 监控器无需支持任何涉及的高层协议. 具体方式如下:

当监控器收到地址解析数据包时, 它始终将 <协议类型, 发送方协议地址, 发送方硬件地址> 录入表中. 它可以从数据包的 ar$hlnar$pln 字段确定硬件和协议地址的长度. 如果操作码为 REPLY, 监控器可以丢弃该数据包. 如果操作码为 REQUEST 且目标协议地址与监控器的协议地址匹配, 则监控器像正常情况一样发送 REPLY. 监控器通过这种方式只能获得一个映射, 因为对 REQUEST 的 REPLY 将直接发送给请求主机. 监控器可以尝试发送自己的 REQUEST, 但这可能导致两个监控器陷入 REQUEST 发送循环, 需谨慎处理.

由于协议和操作码未合并为一个字段, 监控器无需知道同一高层协议的哪个请求操作码与哪个回复操作码对应. 长度字段也应提供足够信息以"解析"协议地址, 尽管它不了解协议地址的含义.

地址解析协议的可用实现也可用于调试不可用的实现. 硬件驱动程序通常会成功广播以太网类型字段为 ether_type$ADDRESS_RESOLUTION 的数据包. 数据包格式可能不完全正确, 因为初始实现可能存在错误, 表管理也可能略有复杂. 由于请求是广播的, 监控器将收到该数据包, 并可根据需要显示以供调试.


示例 (An Example)

设机器 X 和 Y 位于同一条 10Mbit 以太网电缆上. 它们的以太网地址分别为 EA(X) 和 EA(Y), DOD Internet 地址分别为 IPA(X) 和 IPA(Y). 设 Internet 的以太网类型为 ET(IP). 机器 X 刚刚启动, 迟早需要向同一电缆上的机器 Y 发送 Internet 数据包. X 知道要发送到 IPA(Y), 并告知硬件驱动程序 (此处为以太网驱动程序) IPA(Y). 驱动程序咨询地址解析模块将 <ET(IP), IPA(Y)> 转换为 48 位以太网地址, 但由于 X 刚刚启动, 它没有此信息. 它丢弃 Internet 数据包, 转而创建一个地址解析数据包:

(ar$hrd) = ares_hrd$Ethernet
(ar$pro) = ET(IP)
(ar$hln) = length(EA(X))
(ar$pln) = length(IPA(X))
(ar$op) = ares_op$REQUEST
(ar$sha) = EA(X)
(ar$spa) = IPA(X)
(ar$tha) = don't care
(ar$tpa) = IPA(Y)

并将此数据包广播给电缆上的所有人.

机器 Y 收到此数据包, 确认它支持该硬件类型 (Ethernet), 支持所指示的协议 (Internet), 且该数据包是发给它的 ((ar$tpa)=IPA(Y)). 它录入 (可能替换任何现有条目) <ET(IP), IPA(X)> 映射到 EA(X) 的信息. 然后它注意到这是一个请求, 于是交换字段, 将 EA(Y) 放入新的发送方以太网地址字段 (ar$sha), 将操作码设置为 reply, 并将数据包直接 (非广播) 发送到 EA(X). 此时 Y 知道如何向 X 发送, 但 X 仍不知道如何向 Y 发送.

机器 X 收到来自 Y 的回复数据包, 形成从 <ET(IP), IPA(Y)> 到 EA(Y) 的映射, 注意到数据包是回复并将其丢弃. 下次 X 的 Internet 模块尝试在以太网上向 Y 发送数据包时, 转换将成功, 数据包将 (有望) 到达. 如果 Y 的 Internet 模块随后想与 X 通信, 这也将成功, 因为 Y 已记住了 X 的地址解析请求中的信息.


可能需要表老化 (table aging) 和/或超时机制. 这些机制的实现超出了本协议的范围. 以下是更详细的描述 (感谢 MOON@SCRC@MIT-MC).

如果主机移动, 由该主机发起的任何连接都将正常工作, 前提是其自身的地址解析表在移动时已清除. 然而, 由其他主机发起的到该主机的连接将没有特别的理由知道要丢弃旧地址. 不过, 48 位以太网地址应该是唯一且永久固定的, 因此不应改变. 如果主机名 (以及某些其他协议中的地址) 被重新分配给不同的物理硬件, 主机可能会"移动". 此外, 根据经验, 始终存在通过硬件或软件错误意外传输错误路由信息的危险; 不应允许其永久存在. 也许连接发起失败应通知地址解析模块删除相关信息, 理由是主机不可达, 可能是因为它已关闭或旧的转换不再有效. 或者, 收到来自主机的数据包应重置用于向该主机传输数据包的地址解析条目中的超时; 如果在适当时间内未收到来自主机的数据包, 则忘记该地址解析条目. 这可能会导致为每个传入数据包扫描表的额外开销. 也许使用哈希或索引可以加快速度.

建议的地址解析数据包接收算法试图减少主机移动时的恢复时间. 回想一下, 如果 <协议类型, 发送方协议地址> 已在转换表中, 则发送方硬件地址将取代现有条目. 因此, 在完美的以太网上, 广播 REQUEST 到达电缆上所有站点, 每个站点都将获得新的硬件地址.

另一种方案是让守护进程 (daemon) 执行超时. 经过适当时间后, 守护进程考虑删除某个条目. 它首先直接向表中的以太网地址发送 (如需要, 进行少量重传) 操作码为 REQUEST 的地址解析数据包. 如果在短时间内未收到 REPLY, 则删除该条目. 请求直接发送以避免打扰以太网上的每个站点. 仅仅忘记条目可能会导致有用信息被遗忘, 而这些信息必须重新获取.

由于主机不传输关于自身以外任何人的信息, 重启主机将使其地址映射表保持最新. 错误信息不能通过在机器间传递而永久存在; 唯一可能存在的错误信息是在不知道某台其他机器已更改其 48 位以太网地址的机器中. 也许手动重置 (或清除) 地址映射表就足够了.

如果认为此问题重要, 守护进程应超时并再次询问, 而不是直接删除条目. 守护进程也可以比本协议做得更好的重传, 因为物理连接但不可达的目标机器 (例如由于软件故障) 不应必须响应请求. 本协议将用于确定下一跳网关的以太网地址, 该网关不应必须响应以太网上的所有地址解析数据包. 这不是一个重大问题, 因为守护进程可以使用地址解析协议来提问, 而不是让地址解析模块使用自己的协议.


  • 官方 RFC: https://www.rfc-editor.org/rfc/rfc826.txt
  • 官方页面: https://datatracker.ietf.org/doc/html/rfc826