LwIP BUG之ARP缓存


在1.4.1中,ARP数据缓存存在一个很明显的缺陷。当IP层试图发送一个IP包时,如果这个目的IP地址在ARP中找不到对应的MAC地址,那么这个IP包会被首先缓存在ARP层,只有当ARP解析到目标MAC地址后,这个IP包才会被发送出去。但是这里的数据缓存过程,有点小问题。

    如果IP包被缓存在ARP中,ARP需要对这个包进行一次拷贝。有一种情况是不需要拷贝的,即IP包对应的pbuf是以PBUF_ROM形式存在,因为这种形式的数据包引用的是外部ROM中的一些固定数据(如静态网页数据,文件数据等等),即使这个IP包被缓存在ARP中后,不会担心所引用数据被别人修改,因此也不会出现数据异常。但是对于其他类型的数据而言(PBUF_RAM,PBUF_POOL,PBUF_REF)ARP需要拷贝一份到PBUF_RAM中并缓冲。为什么必须要拷贝呢,这里面的历史很长,见这里:

    好了,我们来看看这里进行pbuf拷贝判断以及拷贝的例子,etharp.c中的etharp_query函数中:

if (arp_table[i].state == ETHARP_STATE_PENDING) {  //如果目的IP地址的MAC解析还没有完成
      struct pbuf *p;
      intcopy_needed = 0;     //标记是否需要拷贝
      p =q;

      //这里循环检测pbuf链表,如果发现任意的非PBUF_ROM节点,那么就需要拷贝
      while(p) { 
          if(p->type != PBUF_ROM){
              copy_needed = 1;
              break;
          }
          p = p->next;
      }

      if(copy_needed) {       //如果需要拷贝,则申请 p->tot_len长度的空间,
          p = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM);
          if(p != NULL) {
                if (pbuf_copy(p, q) !=ERR_OK) {     //拷贝pbuf链表
                    pbuf_free(p);
                    p = NULL;
          }
        }
      }

    这里的问题是,经过while(p)的循环后, p->tot_len并不是原始IP数据包的长度了,而是第一个非PBUF_ROM节点处的 tot_len,因此如果我们试图发送一个pbuf(PBUF_ROM)->pbuf( PBUF_RAM/PBUF_POOL)->....类型的数据包时,内核就必然出错(assert发生)。
    这里正确的写法是:
          p =pbuf_alloc(PBUF_RAW,  q->tot_len ,  PBUF_RAM);
   值得庆幸的是,在内核中,极少产生这种 pbuf(PBUF_ROM)->pbuf( PBUF_RAM/PBUF_POOL )->....类型的数据包,因此内核这种异常也很难被跑到。但是这是一个很明显的代码设计缺陷,值得引起大家的注意。


  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
lwIP(lightweight IP)是一个轻量级的TCP/IP协议栈,用于嵌入式系统中。移植lwIP协议栈可以使嵌入式设备具备网络通信能力。 在rt-thread操作系统中进行lwIP协议栈的移植可以实现网络通信的功能。其中的ping实验是一个常用的网络测试工具,用于测试网络连接是否正常。 移植lwIP协议栈之后,为了进行ping实验,需要进行以下几个步骤: 1. 配置网络参数:需要设置设备的IP地址、子网掩码和网关等参数,使设备能够与网络正常通信。 2. 创建ping应用程序:在rt-thread中,可以通过创建一个ping的应用程序来实现ping命令的功能。该应用程序会向指定的IP地址发送ICMP Echo Request包,并等待接收到相应的ICMP Echo Reply包。 3. 实现ping应用程序:在rt-thread中,可以使用lwIP提供的API函数来实现ping应用程序。需要创建一个线程,不断地向指定的IP地址发送ICMP Echo Request包,并等待接收到相应的ICMP Echo Reply包。 4. 解析ICMP Echo Reply包:当接收到ICMP Echo Reply包时,需要解析其中的字段,判断该包是否表示成功的ping应答。可以通过比较包的标识字段、序号字段和校验和字段等来判断应答的正确性。 通过以上步骤,lwIP协议栈在rt-thread操作系统中完成了ping实验的移植工作,可以通过ping命令来测试网络连接情况。实验结果将显示每次ping的延迟时间和成功率等信息,这些信息对于网络连接的调试和监测非常有用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值