⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 arp协议实现原理.txt

📁 UCOS-II移植心得,对于移植操作系统的工程师有帮助
💻 TXT
📖 第 1 页 / 共 2 页
字号:
              |                 ------------
              |                 |  包分发  |
              |                 ------------
              |                      |
              |                      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

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -