我爱嵌入式系统

当前位置:首页 > 软件天地 > 业内资讯 > 详细内容
ARP协议实现原理
发布时间:2009/11/13  阅读次数:1548  字体大小: 【】 【】【

                                 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 |
                       |             |
                       ---------
                                               图3 ARP处理过程
                                              
       0                                 8                             16                           24                             31                                      
       ---------------------------------------------------------------------
       |                         硬件类型                       |                       协议类型                         |
       ---------------------------------------------------------------------
       |硬件地址长度(HLEN)|协议长度(PLEN)|                             操作                           |
       ---------------------------------------------------------------------
       |                                                 发送方首部(八位组0-3)                                         |
       ---------------------------------------------------------------------
       |           发送方首部(八位组4-5)           |           发送方IP地址(八位组0-1)       |
       ---------------------------------------------------------------------
       |         发送方IP地址(八位组2-3)         |               目标首部(八位组0-1)           |
       ---------------------------------------------------------------------
       |                                                 目标首部(八位组2-5)                                             |
       ---------------------------------------------------------------------
       |                                               目标IP地址(八位组0-3)                                           |
       ---------------------------------------------------------------------
                                                               图4 ARP包结构
      
       如图3,整个ARP处理过程,我主要用5个函数实现。ARP初始化(ARP_init)、ARP请求(ARP_request)、ARP应答(ARP_answer)、ARP回应处理(ARP_process)、IP包接收预处理(IP_in)。在实现网卡驱动程序后,所有ARP处理操作就是填写ARP包(ARP包结构见图4),详见伪代码清单。
       ARP_init完成ARP表初始化,概括说就是ARP表state字段清0。
       ARP_request完成ARP请求操作。ARP协议要求程序根据子网掩码判断IP地址是否属于同一子网,如果在同一子网内,ARP请求目的MAC地址,否则请求默认网关MAC地址。
       ARP_answer比较简单,只要交换ARP请求包地址内容,填写自己的MAC地址和很少的改动后发送即可。
       ARP_process完成ARP回应回来的信息处理。主要进行ARP表的学习和更新。
       IP_in完成IP包接收预处理,用于提取地址映射信息,以便主动学习和及时更新。我的程序不会主动学习不是发给自己IP地址的MAC地址信息,因为ARP表在51中的容量有限,只有频繁用到的地址对才应该存放在里面,否则一旦出现“颠簸”,ARP表就失效了。
       有的ARP实现方案采用数据驱动方式,参数可配置,使用统一的程序,通过加载不同的配置数据,执行不同的操作。这样做使程序版本统一,不同的应用只要加载不同的配置数据即可,不用更换程序,有利于后期维护。但是考虑到51资源紧张和安全性,我的方案只能显示ARP表不允许修改其内容,用户可发挥想象力在此处增加新功能。另外,ARP程序应该记住上一次发过的请求,以避免重发,但同样考虑到资源紧张,也免了。其实无所谓,重发就重发了。表满处理采用有损性能的加速算法,快速有效。另外,本程序不能直接用于嵌入式网关产品。
       uCOS51操作系统本身提供了良好的内存管理功能,我利用它设置了大中小三种缓冲区存放不同类型的数据包。内存使用前申请,使用后释放,有效利用了资源。
       系统特点是:1.抢占式优先级;2.消息驱动;3.串行服务器模式。
       系统优点是:1.等待时不耗费CPU资源;2.有超时保护,不会死锁;3.思路清晰易懂。
       系统基于中断驱动,使用Int0做网卡中断输入口。ISR寄存器只用到4位:OVW 收溢出错/TXE 发被中断错/PTX   发送成功/PRX 接收成功。TCP/IP协议栈做成任务,脱离内核。整体框架如图5、6、7所示。主程序框架见伪代码清单(RxSem和TxSem初始化为0)
      
                       ----------
                       |网卡中断|
                       ----------
                               |
                               V
                       ----------   |>
                       |发信号量|   |   收完/收溢出错
                       |SemPost |---->-------------- RxSemPost
                       ----------   |>
                               |             |   发完/发被中断错
                               ---------->-------------- TxSemPost
                   图5 网卡中断处理程序
                  
                  
                               进入
                                 |     ------
                                 V     |       |                                                   发
                         ----------     |                                             低优先级
         ------> |   等待   |<---    
         |             |TxQPend |<---------------------                 -----
         |             ----------                                         |                   | |
         |                     | TxQFIFO非空                           |                   | |
         |                     V                                                   |     ---<---| |---<---
         |             ----------                                         |     数据源 | |   各任务发送来的数据
         |             | 发送包 |                                         |                   | |
         |             ----------                                         |                 -----
         |                     |                                                   |               TxQFIFO
         |                     V                                                   |
         |     ---------------------                           |
         |     |       释放内存             |                           |
         |     |(包已存入网卡RAM里)|                           |
         |     ---------------------                           |
         |                     |       -----                                 |
         |                     V       |     |                                 |
         |             -----------   |                                 |
         |             |   等待     |<--                                 | (等效发送包被抛弃)
         |             |TxSemPend|<-----------               |
         |             -----------                     |               |
         |                     | 发完/超时             |               |
         |                     V                                 |               |
         | Y   ----------------       -----------     |
         -<---| 发送成功吗? |       |重发第n次|     |
                   |(无错且不超时)|       |     n<N     |     |
                   ----------------       -----------     |
                                 | N                           /^\             |
                                 V                 N             |               |
                     ------------------>------               |
                     |已发了N次吗?|---------->--------
                     ---------------             Y
                          
                           图6 发送流程图
                          
                          
                                                                       进入
                                                                         |     -----
                                                                         V     |     |                                             收
                                                               -----------   |                                       高优先级
                         ------------------>|     等待   |<--
                         |               --------->|RxSemPend|<---------------
                         |               |                 -----------             /|\       /|\
                         |               |                           | 收到包 或     |           |
                         |               |                           V 收错 或         |           |
                         |               |                           | 超时               |           |
                         |               |                 -----------               |   ----------
                         |               |                 |存并清ISR|               |   |复位网卡|
               -----------     |                 -----------               |   ----------
               |RxSemPost|     |                           |                         |     /^\   /^\
               -----------     |                           V                         |       |       |
                         |               |           --------------------   |       |       |
                         |               |           |超时且无新包且无错| Y|       |       |
                         |               |           |       (防死锁)           |->-       |       |
                         |               |           --------------------             |       |
                       /|\             |(不执行             | N                               |       |
                         |               |RxSemPost)       V                                   |       |
                         |               |                 ------------   Y                 |       |
                         |               |                 | 收溢出错 |--->---------       |
                         |               |                 | ISR之OVW |                                 |
                         | Y           | N             ------------                                 |
               ------------------                     | N                                         |
               |网卡中还有包吗?|                     V                                             |
               |   CURR!=BNRY+1   | ------------------------   Y             |
               ------------------ |读出包头,查有无逻辑错|--->-------
                             |                     ------------------------
                           /|\                                       | N
                             |                                         V
                             |                     ------------------------
                     ----------           |按包长度申请合适的大中|
                     |释放内存|           |小号内存,并存入整个包|
                     ----------           |,再调整BNRY                   |
                         /^\ /^\             ------------------------
                           |     |                                   |
                           |     |                                   V
                           |     |     N   ----------------------------
                           |     ---<---|是否是发给自己IP地址的包?|
                           |                   ----------------------------
                           |                                           | Y
                           |                                           V
                           |                                 ------------
                           |                                 |   包分发   |
                           |                                 ------------
                           |                                           |
                           |                                           V
                           |                     ----------------------------
                           |                     |               |               |               |
                           |                     V           -------------------------- IP_in过滤
                           |                     |               V               V               V
                           |                   ARP     ICMP(Ping)   UDP           TCP
                           |                     |               |               |               |
                           |                     ----------------------------
                           |                                           | 串行处理
                           |                                           | (32bitMCU可设计成并发模式)
                           |---------<-------------
                                
                                                           图7 接收流程图
                
       我仔细检查了几遍,似乎比较完备了,各种情况下均可以正常工作。在超负荷流量下,只会抛包,不会死机。当然,由于本人接触资料有限和个人局限性,肯定有错误和疏漏之处,希望大家提出意见和建议。
      
伪代码清单:
ARP_init() //ARP缓存初始化
{
   for(i=0;i<ARPTabSize;i++)
       ARPTable[i].status=0;
}

ARP_request(目的IP地址) //ARP请求
{
//判断IP地址是否属于同一子网的任务交给上层软件处理
//(由它决定请求网卡IP地址还是默认网关IP地址),
//这有利于减少代码量。

   //申请小号内存
   pARP=OSMemGet();

   //填以太网帧
   以太网协议=0x0806;//ARP协议
   目的MAC地址=0xffff;//广播地址
   源MAC地址=自己的MAC地址;

   //填ARP表
   硬件类型=0x0001;
   协议类型=0x0800;
   硬件地址长度=0x06;
   协议长度=0x04;
   操作=0x0001;//请求
   发送方首部=自己的MAC地址;
   发送方IP地址=源IP地址;
   目标首部=0x0000;
   目标IP地址=目的IP地址;
  
   //填充PAD
   没有内容处填充0;

   //发送ARP包至TxQFIFO缓存
   OSQSend(QID,*pARP);
}

ARP_answer(*pARP) //ARP应答
{
   学习/更新ARP缓存表;
  
   //修改收到的ARP包,形成ARP应答
   //填以太网帧
   目的MAC地址=对方(网卡/网关)发来的源MAC地址;
   源MAC地址=自己的MAC地址;

   //填ARP表
   目标首部=发送方首部;发送方首部=自己的MAC地址;
   交换发送方IP地址和目标IP地址;
   操作=0x0002;//ARP应答

   //发送ARP包至TxQFIFO缓存
   OSQSend(QID,*pARP);
}

ARP_process(*pARP) //ARP应答处理
{
   //更新
   for(i=0;i<ARPTabSize;i++){
       if(ARPTab[i].status==1){
           if(ARPTab[i].IPAdr==收到的ARP应答包源IP地址){
               ARPTab[i].ttl=最大寿命;
               ARPTab[i].IPAdr=收到的包的源IP地址;
               ARPTab[i].MACAdr=收到的包的源MAC地址;
               return;
           }
       }
   }
  
   //学习
   for(i=0;i<ARPTabSize;i++){
       if(ARPTab[i].status==0){
           ARPTab[i].status=1;
           ARPTab[i].ttl=最大寿命;
           ARPTab[i].IPAdr=收到的包的源IP地址;
           ARPTab[i].MACAdr=收到的包的源MAC地址;
           return;        
       }
   }

   //表满处理,有损性能的快速算法
   ARPTab[index].status=1; //注:index为全局变量,保存ARP缓存表项索引。每次处理加1取模。
   ARPTab[index].ttl=最大寿命;
   index++;
   if(index>=ARPTabSize) index=0;
}

IP_in(*pIP) //IP包过滤(ARP地址学习) 注:这里处理的是IP包,伪代码与上面程序相似,但源代码差别很大。
{
   //更新
   for(i=0;i<ARPTabSize;i++){
       if(ARPTab[i].status==1){
           if(ARPTab[i].IPAdr==收到的IP包源IP地址){
               ARPTab[i].ttl=最大寿命;
               ARPTab[i].IPAdr=收到的包的源IP地址;
               ARPTab[i].MACAdr=收到的包的源MAC地址;
               return;
           }
       }
   }
  
   //学习
   for(i=0;i<ARPTabSize;i++){
       if(ARPTab[i].status==0){
           ARPTab[i].status=1;
           ARPTab[i].ttl=最大寿命;
           ARPTab[i].IPAdr=收到的包的源IP地址;
           ARPTab[i].MACAdr=收到的包的源MAC地址;
           return;        
       }
   }

   //表满处理,有损性能的快速算法
   ARPTab[index].status=1; //注:index为全局变量,保存ARP缓存表项索引。每次处理加1取模。
   ARPTab[index].ttl=最大寿命;
   index++;
   if(index>=ARPTabSize) index=0;
}

timer() //软定时器任务,用于ARP老化
{
   for(;;){
       taskDelay(1秒);
       for(i=0;i<ARPTabSize;i++){
           if(ARPTab[i].status==1){
               if(ARPTab[i].ttl==0)
                   ARPTab[i].status=0;
               else
                   ARPTab[i].ttl--;
       }
   }
}

主程序框架:
       initNIC       //初始化网卡
       //创建资源
       TxSem和RxSem信号量
       TxQFIFO队列
       大中小内存设立
       //创建任务
       收
       发
       。
       。
       。
      
参考文献:
1。《用TCP/IP进行网际互连》(第3版)第一、二、三卷 DOUGLAS E.COMER著 电子工业出版社
2。www.laogu.com
3。www.sics.se/~adam/lwip/ 的uip6

我要评论
  • 匿名发表
  • [添加到收藏夹]
  • 发表评论:(匿名发表无需登录,已登录用户可直接发表。) 登录状态:未登录
最新评论
所有评论[3]
  • 评论人:[匿名] 时间: [2019/8/23 4:12:31] IP:[5.188.84.7*]
  • Combine Priligy Viagra Cephalexin Reaction a href=http//buycialcheap.comcialis prices/a Viagra Erfahrungen Kaufen Generic Free Shipping Clobetasol 0.05% Psoriasis Accutane Without A Perscription
  • 评论人:[匿名] 时间: [2019/4/3 6:06:44] IP:[5.188.45.16*]
  • Cephalexin Capsules Ip 500mg Cialis E Impotenza Flagyl Online No Prescription a href=http//viaaorder.comviagra/a Levitra El Mejor Acticin Best Website Commander Viagra Sans Ordonnance
  • 评论人:[匿名] 时间: [2019/3/7 7:58:20] IP:[5.188.45.16*]
  • On Line Amoxicilina Discount Medicine Medikament Viagra 50 Mg a href=http//buycialonline.comcialis online/a Levitra Espanol

51RTOS.com 版权所有  

Copyright 20006-2009 我爱嵌入式 ( 51RTOS.com ) All rights reserved 沪ICP备09080633号