PS: 这是我毕业设计时翻译的选文.之前科研训练时虽然也有译过,但是因为发到了Blog上,网上已经能够搜到,怕咱毕设老师误解,所以重译了一篇.
为啥要贴这篇,再议.
--------------------------------------------------
以太网地址解析协议
——将网络层协议地址转换为48位以太网地址以在以太网硬件基础上传输
摘要
设想建立在一条10Mbit以太网电缆之上的协议P需要通过它的路由架构从发送端主机S传输数据到接收端主机T,那么为了传输这一以太网数据包,必须生成一个48位的以太网地址。然而,协议P的主机地址未必与以太网地址相互兼容(长度和值有所差异)。这时就需要一个协议,以便动态地发布将一个协议P地址A转换为48bit以太网地址所需的信息。
实际上这样的一个协议未必局限在10Mbit以太网硬件之上。一些通过电波传输网络包的网络设备就是这类硬件的典型代表。
此处提议的这一协议是作者与很多人共同讨论得出的成果,其中影响尤大的人包括:J. Noel Chiappa, Yogen Dalal和James E. Kulp,并从David Moon那里得到了极有帮助的建议。
[本篇RFC的目的在于展示一种转换协议地址(例如IP地址)到本地网络地址(例如以太网地址)的方法,这在当前是一个ARPA网络社区中的热门议题。作者建议你能够发表你自己的相关考虑和评论。本篇并非某个网络标准的定义。]
注记
这一协议最初是为DEC/Intel/Xerox的10Mbit以太网设计的,不过也可以用于其他类型的网络。多数讨论都将是直接针对10Mbit以太网的。总之,虽然往往能够适应其他环境,本篇依然是针对以太网的。
DOD网络协议在此文中将会被表述为Internet。
本文中的数字基于以太网标准,使用高字节优先表述法。这同与某些机器(诸如PDP-11和VAX)的计数法相反。因此,应当特别关注下文中描述的操作码字段(ar$op)。
一个专家之间的共识是管理硬件名字空间的重要性。在官方的主家族建立之前,相关的建议应当提交到如下地址:
David C. Plummer
Symbolics, Inc.
243 Vassar Street
Cambridge, Massachusetts 02139
也可以发送邮件到邮箱DCP@MIP-MC。
问题
世界就像是一个杂乱丛林,而网络化的游戏则更增加了这片丛林的杂乱。在网络架构的几乎每一个层上都存在着若干可用的协议。例如,在高层上存在着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位以太网地址的相互对应关系。
动机
伴随越来越多的厂商开始支持由DEC,Intel和Xerox联合制定的统一的网络架构,10Mbit以太网的使用变得越来越广泛。随之而来的是,越来越多针对这一接口的软件应运而生。这里因此产生了一个分岔:(1)每个实现者都各自实现他们各自的地址转换方法,或者(2)所有实现者使用一个相同的标准化的转换方法,以此确保他们的代码能够不做修改地在其他系统上发布和运行。作者提议尝试建立这样的标准。
定义
为以太网数据包首部的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)。
包格式
为了建立协议-地址对与48位以太网地址之间的联系,需要有一个具体化的地址解析协议的格式。这一包格式如下。
以太网传输层[1](无需用户访问):
48位: 目的地以太网地址
48位: 发送方以太网地址
16位: 协议类型 type=ether_type@ADDRESS_RESOLUTION
以太网包数据:
16位: (ar$hrd) 硬件类型
16位: (ar$pro) 协议类型。对于以太网硬件,该值源于类型字段集合ether_typ$<protocol>。
8位: (ar$hln) 硬件地址长度
8位: (ar$pln) 协议地址长度
16位: (ar$op) 操作码(ares_op$REQUESST或ares_op$REPLY)
n字节: (ar$spa) 发送方硬件地址,n为ar$hln字段值
m字节: (ar$tha) 本包目标的硬件地址
m字节: (ar$tpa) 目标的协议地址
包生成
当包被发送并通过网络层时,路由决定了包的下一跳的协议地址以及它期望在何种硬件上通过目标协议地址找到主机。当硬件为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设置为硬件广播地址。这将导致这个包通过路由架构被广播到以太网电缆上的所有工作站。
包接收
当一个地址解析包被收到时,接收的以太网模块就会依据类似于下述方法的算法将包交付给地址解析模块。
当遇到条件不符合时,处理的过程就会结束,而包自身则会被抛弃。
自身是否包含ar$hrd描述的硬件?
Yes(几乎可以确定)
[检查硬件地址长度ar$hln(可选项)]
?自身是否使用ar$pln当中描述的协议?
Yes:
[检查协议地址长度ar$pln]
Merge_flag := false
If 协议-地址对匹配
已存在于自身转换表中,将发送方硬件地址域作为更新到自身相应项中并将Merge_flag设置为true
?自身是否拥有目标协议地址?
Yes:
If Merge_flag is false
将相应键值对添加到转换表
?操作码是否ares_op$REQUEST?
Yes:
交换硬件地址和协议地址域,将本地硬件地址和协议地址置入发送者字段
设置ar$op字段为ares_op$REPLY
将包发送到与原包的源地址相同的新目标硬件地址
注意,协议-协议地址-硬件地址 三元组在检查opcode之前就已经被合并到表中。这是基于双向通信的假定:如果A有需要传达给B的数据,则B也有需要传达给A的数据。同样需要注意的是如果某个实体已经具有了 协议-协议地址-物理地址 三元组,则新的物理地址将取代旧的。相关问题章节阐述了这种行为的动因。
概括:ar$hrd和ar$hln字段允许本协议和包格式用于非10Mbit以太网的链路系统。对于10Mbit以太网链路系统,ar$hrd取值1,ar$hln取值6。对于其他链路系统,这两个字段的值与以太网链路系统无关,而与具体需要解析的协议系统自身有关。
方案溯源
定期广播的想法被明确否定。设想在单个以太网链路中有100个工作站,每个工作站每隔10分钟进行一次地址解析信息广播,链路本身每隔6秒发送一个数据包。这看上去是合理的,但是实际上不尽如人意。设想多数工作站实际上并没有与其它工作站通信(因此在它们的解析表中拥有100个多余的表项),而主要与某个服务端主机、文件服务器或是网桥通信的情况。实际使用的协议最好只在需要的时候发布信息,并且只在每台机器引导的时候发送一次。
本格式并不允许对相同的数据包进行多重解析,这是出于简单性的考虑。如果允许对包的多次解析,则可以想见更大的复杂度,而且包中的多数数据都会毫无意义。设想一个兼容四种协议的网桥对某个工作站提供四种协议地址,其中将会有三种都不为工作站所用。
本协议允许包的缓冲以及在应答生成时报的重用。应答包和请求包拥有相同的长度,并且有的字段都是相同的。
硬件协议字段(ar$hrd)字段的值是从一个列表当中获取的。当前唯一定义的值是10Mbit以太网的值(ares_hrd$Ethernet = 1)。前文还讨论过使用电波的网络链路,在这些链路上使用本协议则需要增加新的值。
对于10Mbit以太网,协议字段(ar$pro)取自ether_type$集合。这是对于现有协议的一个理所应当的重用。将这个值包含在操作码(ar$op)中会显著地减少本协议下能够解析的协议的数量并增大调试的复杂度(见后文网络监视和调试章节)。这样的设计寄希望于我们不会见到第32768种协议,然而墨菲定律告诉我们不应心存这种侥幸。
从理论上讲,长度字段(ar$hln和ar$pln)是多余的,协议地址的长度可以通过硬件类型字段(ar$hrd)和协议字段(ar$pro)推断出来。这关系到一致性检查的问题,并且存在一些网络监控和调试方面的考虑。
操作码用于决定一个包是请求(将会导致应答)还是对之前请求的应答。为它分配16位实在过多了,但是作为一个标记位,这么多位还是需要的。
发送方硬件地址和发送方协议地址毫无疑问是必须的。这些字段的内容将会被置入到转换表中。
目标协议地址对于请求形式的包是必需的,机器必须借此确定是需要往转换表中填入信息还是要发送应答。对于应答形式的包来说,如果仅仅是为了响应一个请求,则该字段并不必需,而仅仅是为了完整性,网络监控以及简化处理算法而存在的。
目标硬件地址是为了完整性和网络监控而加入的。对于请求形式的包来说,这个字段没有意义,仅仅是发送请求的机器的序号而已。对于应答包来说,它的含义是发送请求的机器的地址。在某些实现中(比如那些不检查14位的以太网帧首部的实现)将这一字段直接发给硬件做为包的目的地址可能会节省一些缓冲或者栈空间。
地址之间没有分隔符。包数据应当被视为一个只有三个字节对的字节流。
网络监视与调试
上述地址解析协议允许一台机器向更高层活动协议(例如:CHAOS、Internet、PUP、DECnet)提供以太网链路的信息。它能够确定何种以太网协议字段被使用,以及对应于各种协议类型的协议地址。事实上,对于监视器来说,并没有必要知道任何高层协议的知识。它主要如下运作:
当一个监视器受到一个地址解析包时,它进入一个表中对应于 协议-发送方协议地址-发送方硬件地址 的表项。它能够通过包的ar$hln和ar$pln字段确定硬件地址和协议地址各自的长度。如果操作码是REPLY监视器就将该包抛弃。如果操作码是一个REQUEST且目标协议地址与监视器中的协议地址相匹配,则监视器正常地发送一个REPLY应答包。监视器只会执行一次映射,同时REPLY将会直接送到发送REQUEST包的请求方。监视器可能会发送其自己的REQUEST,但是这可能会导致两个监视器之间循环发送REQUEST包,应当小心避免。
因为协议和操作码并没有被包含到同一个字段中,监视器无需知道相同级别的协议中哪个请求操作码与哪个应答操作码相关。长度字段应当已经为解析协议地址提供了充足的信息,尽管它并没有记叙协议地址的含义。
一个能够正常工作的地址解析协议的实现能够用于调试一个尚未投入使用的实现。假定上一个硬件驱动应当能够顺利地广播以太网类型字段为ether_type$ADDRESS_RESOLUTION的数据包。包的格式可能并不完全正确,因为最初的实现可能包含bug,而表管理器的构造也可能有点投机取巧。因为请求是广播的,如果调试需要,监视器将会收到包并能够显示它。
例子
假定在一个10Mbit以太网电缆上存在两台机器X和Y,它们具有以太网地址EA(X)和EA(Y),并具有DOD Internet地址IPA(X)和IPA(Y)。令Internet的以太网类型为ET(IP)。机器X刚刚启动,并早晚需要发送一个Internet数据包给机器Y。X知道它需要发送数据给IPA(Y)并告诉硬件驱动(具备以太网驱动)IPA(Y)。驱动参考地址解析协议模块将 ET(IP)-IPA(Y) 对转换为48位以太网地址,然而因为X刚刚启动,它并没有这些信息。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机器获取这个包,并确定它理解硬件类型(以太网)并使用相同的协议(Internet)且包是发送给它的((ar$tpa)=IPA(Y))。Y设置(或者替换现存项) ET(IP)-IPA(X)映射到EA(X),Y随后注意到这是一个请求包,因此交换其字段,将EA(Y)送入新的发送者以太网地址字段(ar$sha),将操作码设置为应答,并将包直接(而非广播)到EA(X)。此时Y已经知道该如何发送给X,而X还不知道如何抵达Y。
X由Y获取应答包,将ET(IP)-IPA(Y)映射到EA(Y),注意到这是应答包并将其舍弃。下一次X的网络模块尝试通过以太网向Y发送包时,转换将会成功,包将直接抵达目标。如果Y的网络模块想要与X通信,它同样会成功,因为Y已经通过X的请求记住了X的地址解析信息。
相关问题
设置表项老化和/或超时可能是值得的。它们的执行不在本协议的范围之内。以下是更详细的描述(根据MOON@SCRC@MIT-MC):如果主机地址发生了改变,假定它的地址解析表此时已经明确,则任何该主机发起的连接都将有效。然而,由其它主机向它发起的连接将无法通过确切的途径获知它的旧地址已经失效。不过,48位以太网地址理论上应该总是唯一且固定的,所以它们不会变化。当主机的名称(在一些其它协议中还包括它的地址)被重新分配至另一不同的物理硬件时,该主机才可以“移动”。此外,我们的经验表明,不正确的路由信息由于硬件或软件错误被偶然传输的危险常常存在;而它的长期存在应该是不被允许的。或许发起连接的失败应该提醒地址解析模块删除这一信息,依据是该主机无法连接,这可能是由于它已经死机或旧的转换已经失效。抑或从主机接收一个包时应在地址解析条目中重设一个timeout值,用于向该主机传输数据包;如果在一个合适的时间长度内没有收到来自该主机的包,相应的地址解析条目将被遗忘。这可能导致在为每个传入包扫描解析表时产生额外开销。也许通过引入哈希或索引可以加快这一过程。
假定中的接收地址解析包所使用的算法旨在减少主机移动之后的恢复时间。我们知道如果协议-地址对已经存在于解析表中,则发送方硬件地址将替代已有的条目。因此,在一个广播一条REQUEST可以传至电缆上所有站点的理想以太网中,每个站点都将得到新的硬件地址。
另一种解决方案是使用后台程序(daemon)控制超时。经过一段合适的时间后,daemon会考虑移除一条记录。它首先将一个带有操作码REQUEST的地址解析包直接发送(如果需要,还会有少量重传)至解析表中的以太网地址。如果短时间内未能收到REPLY,该条目将被删除。为了不打扰以太网上的所有站点,这一请求是直接发送的。仅仅遗忘条目将有可能导致有用信息的丢失,这些信息需要重新获取。
由于主机并不传输除它自身以外的信息,重新启动主机将导致其地址映射表的更新。错误信息不可能以在机器之间传播的形式持续存在;错误信息存在的唯一可能情况是一台机器不知道其它机器已经改变了它的48位以太网地址。或许人工重启(或清除)地址映射表可以解决这一问题。
如果这个问题被认为是重要的,它显然需要更深入的思考。任何地址解析型的协议都可能导致该问题的发生。