【lwip】08-ARP协议一图笔记及源码实现( 六 )

etharp_request_dst()

  • 发起ARP标准请求包 。(广播包)
/** * Send an ARP request packet asking for ipaddr. * * @param netif the lwip network interface on which to send the request * @param ipaddr the IP address for which to ask * @return ERR_OK if the request has been sent *ERR_MEM if the ARP packet couldn't be allocated *any other err_t on failure */err_tetharp_request(struct netif *netif, const ip4_addr_t *ipaddr){LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_request: sending ARP request.\n"));return etharp_request_dst(netif, ipaddr, &ethbroadcast);}8.7.4 发送ARP IP探测包etharp_acd_probe()
  • 发起ARP IP探测 。
  • 用于发送探测消息进行地址冲突检测 。
/** * Send an ARP request packet probing for an ipaddr. * Used to send probe messages for address conflict detection. * * @param netif the lwip network interface on which to send the request * @param ipaddr the IP address to probe * @return ERR_OK if the request has been sent *ERR_MEM if the ARP packet couldn't be allocated *any other err_t on failure */err_tetharp_acd_probe(struct netif *netif, const ip4_addr_t *ipaddr){return etharp_raw(netif, (struct eth_addr *)netif->hwaddr, &ethbroadcast,(struct eth_addr *)netif->hwaddr, IP4_ADDR_ANY4, &ethzero,ipaddr, ARP_REQUEST);}8.7.5 发送ARP IP宣告包etharp_acd_announce()
  • 发起ARP IP宣告 。
  • 用于发送地址冲突检测的公告消息 。
/** * Send an ARP request packet announcing an ipaddr. * Used to send announce messages for address conflict detection. * * @param netif the lwip network interface on which to send the request * @param ipaddr the IP address to announce * @return ERR_OK if the request has been sent *ERR_MEM if the ARP packet couldn't be allocated *any other err_t on failure */err_tetharp_acd_announce(struct netif *netif, const ip4_addr_t *ipaddr){return etharp_raw(netif, (struct eth_addr *)netif->hwaddr, &ethbroadcast,(struct eth_addr *)netif->hwaddr, ipaddr, &ethzero,ipaddr, ARP_REQUEST);}8.8 数据包发送分析8.8.1 数据发包处理简述(ARP相关)主要分析ARP协议层的处理 。
IP层数据包通过ip4_output()函数传递到ARP协议处理 。通过ARP协议获得目标IP主机的MAC地址才能封装以太网帧,在链路层转发 。
etharp_output()收到IP层发来的数据包后按一下逻辑分支处理:
  • 对于广播或者多播的数据包:调用ethernet_output()函数直接把数据包丢给网卡即可 。
    • MAC的多播地址范围:01:00:5E:00:00:00 —— 01:00:5E:7F:FF:FF
  • 对于单播数据包:
    • 遍历ARP缓存表:遍历时,可以从当前网卡上次发送数据包使用的arp entry开始查起,找到就调用etharp_output_to_arp_index()把IP数据包转交给链路层转发 。
      • etharp_output_to_arp_index()概述里面会更新维护ARP缓存表当前arp entry 。
    • 发起ARP请求:如果缓存表中没有当前IP数据包目标IP映射的MAC地址,就需要调用etharp_query(),把IP数据包转交给ARP协议处理 。
      • etharp_query()会发起ARP请求,在ARP请求过程中,把这些IP层的数据包保存到当前ARP条目的entry的挂起缓存队列中 。直到收到ARP响应或者ARP请求超时为止 。
对于PBUFF_ERFPBUF_POOLPBUF_RAM类型的数据包是不允许直接挂到ARP entry的挂起缓存队列上的,因为内核等待目标主机的ARP应答期间,这些数据有可能会被上层改动,所以LwIP需要将这些pbuf数据包拷贝到新的空间,等待发送 。
8.8.2 etharp_output():IP数据包是否ARP协议处理解析和填写以太网地址头为传出IP数据包 。

经验总结扩展阅读