【lwip】08-ARP協議一圖筆記及源碼實現( 二 )


  • 1:ARP請求 。
  • 2:ARP應答 。
  • 3:RARP請求 。
  • 4:RARP應答 。
  • 發送端以太網地址(6) 。
  • 發送端IP地址(4) 。
  • 目的以太網地址(6) 。
  • 目的IP地址(4) 。
  • 小筆記:
    • 看到上述的報文簡述后,會發現以太網的數據幀首部和ARP請求數據報中都有發送端的硬件地址 。這個很正常,因為兩者所處的OSI層級不一樣,前者是鏈路層處理的數據幀頭需要的硬件地址 。后者是網絡層處理的ARP請求數據報中的重要信息 。
    • ARP請求有些信息會留空,如ARP請求時,目的端的硬件地址不需要填充 。而協議中保留,是為了實現ARP請求和ARP應答的報文字段一致 。
    ARP簡要交互:
    對于一個ARP請求來說,除目的端硬件地址外的所有其他的字段都有填充值 。
    當系統收到一份目的端為本機的ARP請求報文后,它就把硬件地址填進去,然后用兩個目的端地址分別替換兩個發送端地址,并把操作字段置為2(ARP應答),最后把它發送回去 。
    ARP交互報文例子圖,wireshark分析:
    【lwip】08-ARP協議一圖筆記及源碼實現

    文章插圖
    8.4 ARP緩存表8.4.1 ARP緩存表簡介每臺主機或路由器在其內存中具有一個ARP緩存表(ARP table),這張表包含IP地址到MAC地址的映射關系 。
    網絡層的IP數據包需要經過鏈路層轉發時,可以直接查詢緩存表是否有這個IP映射的MAC 。
    如果有,目標鏈路層數據幀的目標MAC就直接使用這個MAC,就能轉發了 。
    如果沒有,通過ARP協議,往鏈路層局域網內廣播一下,詢問下有沒有這個IP對應的結點設備,如果有就把這個IP對應的鏈路層設備的MAC返回到這個主機,然后這個主機的鏈路層使用這個MAC發送數據幀出去 。而且可以把這個MAC及其對應的IP保存到自己的ARP緩存表中,方便下次直接使用 。當然,這個映射也有過期檢查,需要超時機制維護 。
    8.4.2 LWIP中的緩存表lwip的緩存表:static struct etharp_entry arp_table[ARP_TABLE_SIZE];
    ARP_TABLE_SIZE默認為10,即是默認能緩存10條ARP映射記錄 。
    8.4.3 ARP緩存表數據結構struct etharp_entry
    struct etharp_entry {#if ARP_QUEUEING/* 指向此ARP表項上掛起的數據包隊列的指針. */struct etharp_q_entry *q;#else /* ARP_QUEUEING *//* 指向此ARP表項上的單個掛起的數據包隊列的指針 */struct pbuf *q;#endif /* ARP_QUEUEING *//* 目標IP地址 */ip4_addr_t ipaddr;/* 當前ARP映射記錄對應網卡信息 */struct netif *netif;/* 目標IP對應的MAC地址 */struct eth_addr ethaddr;/* 當前netry的生存時間 */u16_t ctime;/* 當前netry的狀態信息 */u8_t state;};
    【lwip】08-ARP協議一圖筆記及源碼實現

    文章插圖
    8.4.4 ARP緩存表數據緩沖隊列struct etharp_q_entry *q;
    這個字段用于指向緩存表的數據包緩沖隊列 。
    在IP層發送一個數據包時,會先在ARP映射表中查找與目的IP地址對應的MAC地址,這樣才能封裝以太網幀,才能在鏈路層把數據包發送出去 。
    但是如果IP層發送一個數據包時,在ARP映射表中查不到對應的硬件地址MAC,就發送一個ARP請求包,在請求過程中,把這個IP層的數據包緩存到這個隊列q先,直到請求成功后,獲取這個IP層數據包IP對應的MAC地址或請求失敗為止 。
    對于PBUFF_ERFPBUF_POOLPBUF_RAM類型的數據包是不允許直接掛到ARP entry的掛起緩存隊列上的,因為內核等待目標主機的ARP應答期間,這些數據有可能會被上層改動,所以LwIP需要將這些pbuf數據包拷貝到新的空間,等待發送 。

    經驗總結擴展閱讀