【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數據包 。

經驗總結擴展閱讀