ARP协议实现原理
作者<asdjf@163.com> 2002/11/01
ARP是Address Resolution Protocol的缩写。中文译做“地址解析协议”,本质是完成网络地址到物理地址的映射。从概念上讲就是找到一个映射方法f,使得“物理地址 = f(网络地址)”。物理地址有两种基本类型:以太网类型和proNET令牌环网类型,网络地址特指IP地址,对映射方法的要求就是高效。具体到以太网,它使用的是动态绑定转换的方法。为什么不直接使用同一种地址,而要这么麻烦呢?因为TCP/IP网络就是为将不同种类计算机互联而发明的,它的体系结构是分层的,层和层之间相互独立,改变物理层的实现不会影响到网络层。
32位IP地址到以太网48位物理地址的映射,采用动态绑定转换的方法会遇到许多细节问题,例如:减少广播,ARP包丢失,物理地址变更(更换网卡)、移动(移动设备到另一子网)、消失(关机)等。一般是设置ARP高速缓存,通过学习、老化、更新、溢出算法处理ARP映射表来解决这些问题。其中,学习指ARP收到任何指向本节点IP地址的ARP/IP包,从中提取出地址对,而ARP缓存中无对应项时,由ARP接收部分添加;老化指为每项设置寿命域,以便代谢掉陈旧的地址映射项;更新指ARP提取到新的地址对时,用其更新缓存里已有的对应项;溢出算法指当缓存满时,采取何种方法替换旧有的地址对儿。
我找到了几个TCP/IP源代码,对比他们的实现,深感差别巨大,灵活多变。有的代码未实现ARP缓存,只用几个全局变量记录源目的IP地址和源目的MAC地址,每次通信前直接操作全局变量,这在使用51单片机,进行点对点通信时不失为一个有效的方案;而有的代码庞大复杂,细节处理精益求精。比如实现了ARP高速缓存、支持多址节点、支持网管查看/动态改变ARP相关参数、重发处理、支持IPv6等。我的看法是:ARP的本质是地址转换,只要抓住这个灵魂,设计的大方向就把握住了。具体实现过程各具特色,因人而异,没有统一要求,有些功能可以不实现,有些优点不能兼得,而唯一不变的只有思想。
我参考了几种已有的IP协议栈并结合51单片机的特点,实现了自己的基于uCOS51的TCP/IP协议栈方案。它只是一种具体的实现范例,不同的人有不同的设计方法。我保证自己的方案可以正常使用并具有较好的完备性。
------------------------------
|状态|寿命ttl|IP地址 |MAC地址| 学习
------------------------------
| 0 | FF |X:X:X:X| XXXX | <--- 老化
------------------------------
| 0 | FF |X:X:X:X| XXXX | 更新
------------------------------
图1 ARP缓存表 表满处理
如图1所示,ARP缓存表由状态、寿命、IP地址、MAC地址4个字段组成。状态字段指示地址对是否有效(0-空闲 1-占用);寿命字段用于老化操作,初始存入最大值,以后由OS时间函数调用,每秒减1,直至为0清除;IP地址和MAC地址字段保存网络地址和物理地址的映射。此处,没有设计发送数据链表首指针和重发记数字段,我把重发操作交给上层软件统一处理,这是本程序的特色。围绕ARP缓存表,完成了4种操作:学习、老化、更新、表满处理,详见伪代码清单。使用OS的Shell命令ls可以查看ARP表的内容,但不支持修改,这个功能对测试很有用。(显示内容举例如图2所示)
%ls
ARP table:
status TTL IP address MAC address
=================================================
01 78 172.18.92.86 0050BABD4C7E
%
图2 ARP缓存表显示内容举例
表满处理
|
v ARP请求
--------- ----------- ---------->
| | 学习/更新 | | <- - - - -
老化--->| ARP表 |<------------| ARP处理 |
| | | | - - - - - >
--------- ----------- <----------
^ ARP应答
|学习/更新
---------
| |
| IP_in |
| |
---------
作者<asdjf@163.com> 2002/11/01
ARP是Address Resolution Protocol的缩写。中文译做“地址解析协议”,本质是完成网络地址到物理地址的映射。从概念上讲就是找到一个映射方法f,使得“物理地址 = f(网络地址)”。物理地址有两种基本类型:以太网类型和proNET令牌环网类型,网络地址特指IP地址,对映射方法的要求就是高效。具体到以太网,它使用的是动态绑定转换的方法。为什么不直接使用同一种地址,而要这么麻烦呢?因为TCP/IP网络就是为将不同种类计算机互联而发明的,它的体系结构是分层的,层和层之间相互独立,改变物理层的实现不会影响到网络层。
32位IP地址到以太网48位物理地址的映射,采用动态绑定转换的方法会遇到许多细节问题,例如:减少广播,ARP包丢失,物理地址变更(更换网卡)、移动(移动设备到另一子网)、消失(关机)等。一般是设置ARP高速缓存,通过学习、老化、更新、溢出算法处理ARP映射表来解决这些问题。其中,学习指ARP收到任何指向本节点IP地址的ARP/IP包,从中提取出地址对,而ARP缓存中无对应项时,由ARP接收部分添加;老化指为每项设置寿命域,以便代谢掉陈旧的地址映射项;更新指ARP提取到新的地址对时,用其更新缓存里已有的对应项;溢出算法指当缓存满时,采取何种方法替换旧有的地址对儿。
我找到了几个TCP/IP源代码,对比他们的实现,深感差别巨大,灵活多变。有的代码未实现ARP缓存,只用几个全局变量记录源目的IP地址和源目的MAC地址,每次通信前直接操作全局变量,这在使用51单片机,进行点对点通信时不失为一个有效的方案;而有的代码庞大复杂,细节处理精益求精。比如实现了ARP高速缓存、支持多址节点、支持网管查看/动态改变ARP相关参数、重发处理、支持IPv6等。我的看法是:ARP的本质是地址转换,只要抓住这个灵魂,设计的大方向就把握住了。具体实现过程各具特色,因人而异,没有统一要求,有些功能可以不实现,有些优点不能兼得,而唯一不变的只有思想。
我参考了几种已有的IP协议栈并结合51单片机的特点,实现了自己的基于uCOS51的TCP/IP协议栈方案。它只是一种具体的实现范例,不同的人有不同的设计方法。我保证自己的方案可以正常使用并具有较好的完备性。
------------------------------
|状态|寿命ttl|IP地址 |MAC地址| 学习
------------------------------
| 0 | FF |X:X:X:X| XXXX | <--- 老化
------------------------------
| 0 | FF |X:X:X:X| XXXX | 更新
------------------------------
图1 ARP缓存表 表满处理
如图1所示,ARP缓存表由状态、寿命、IP地址、MAC地址4个字段组成。状态字段指示地址对是否有效(0-空闲 1-占用);寿命字段用于老化操作,初始存入最大值,以后由OS时间函数调用,每秒减1,直至为0清除;IP地址和MAC地址字段保存网络地址和物理地址的映射。此处,没有设计发送数据链表首指针和重发记数字段,我把重发操作交给上层软件统一处理,这是本程序的特色。围绕ARP缓存表,完成了4种操作:学习、老化、更新、表满处理,详见伪代码清单。使用OS的Shell命令ls可以查看ARP表的内容,但不支持修改,这个功能对测试很有用。(显示内容举例如图2所示)
%ls
ARP table:
status TTL IP address MAC address
=================================================
01 78 172.18.92.86 0050BABD4C7E
%
图2 ARP缓存表显示内容举例
表满处理
|
v ARP请求
--------- ----------- ---------->
| | 学习/更新 | | <- - - - -
老化--->| ARP表 |<------------| ARP处理 |
| | | | - - - - - >
--------- ----------- <----------
^ ARP应答
|学习/更新
---------
| |
| IP_in |
| |
---------