<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                ARP數據包的處理函數為etharp _input(),在這里它完成兩個任務: 1. 如果收到的是ARP應答包,說明本機之前發出的ARP請求包有了回應,就根據應答包更新自身的ARP緩存表; 2. 如果收到的是ARP請求包,如果包中的目標IP地址與主機IP地址匹配,除了記錄原主機的IP與MAC地址,更新自身的ARP表外,還要向源主機發送一個ARP應答包。但是如果如果包中目標IP地址與主機IP地址不匹配,則盡可能記錄源主機的IP與MAC地址,更新自身的ARP表,并丟棄該請求包,為什么說是盡可能呢,因為主機的ARP緩存表是有限的,不可能記錄太多的ARP表項,所以在有空閑的表項時才記錄,如果沒有空閑的表項,ARP覺得它自己已經盡力了,也記不住那么多表項。 etharp _input()函數的源碼具體見代碼清單 10 9。 ``` 1 void 2 etharp_input(struct pbuf *p, struct netif *netif) 3 { 4 struct etharp_hdr *hdr; 5 6 ip4_addr_t sipaddr, dipaddr; 7 u8_t for_us; 8 9 LWIP_ASSERT_CORE_LOCKED(); 10 11 LWIP_ERROR("netif != NULL", (netif != NULL), return;); 12 13 hdr = (struct etharp_hdr *)p->payload; 14 15 /* 判斷ARP包的合法性 */ 16 if ((hdr->hwtype != PP_HTONS(LWIP_IANA_HWTYPE_ETHERNET)) || 17 (hdr->hwlen != ETH_HWADDR_LEN) || 18 (hdr->protolen != sizeof(ip4_addr_t)) || 19 (hdr->proto != PP_HTONS(ETHTYPE_IP))) (1) 20 { 21 LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, 22 ("etharp_input: packet dropped, wrong hw type, hwlen, proto, 23 protolen or ethernet type(%"U16_F"/%"U16_F"/%"U16_F"/%"U16_F")\n", 24 hdr->hwtype,(u16_t)hdr->hwlen, hdr->proto, (u16_t)hdr->protolen)); 25 26 ETHARP_STATS_INC(etharp.proterr); 27 ETHARP_STATS_INC(etharp.drop); 28 29 pbuf_free(p); 30 return; 31 } 32 ETHARP_STATS_INC(etharp.recv); 33 34 //拷貝源IP地址與目標IP地址 35 IPADDR_WORDALIGNED_COPY_TO_IP4_ADDR_T(&sipaddr, &hdr->sipaddr); (2) 36 IPADDR_WORDALIGNED_COPY_TO_IP4_ADDR_T(&dipaddr, &hdr->dipaddr); (3) 37 38 /* 看看主機網卡是否配置了IP地址 */ 39 if (ip4_addr_isany_val(*netif_ip4_addr(netif))) (4) 40 { 41 for_us = 0; 42 } 43 else 44 { 45 /* 判斷目標IP地址與主機IP地址是否一樣 */ 46 for_us = (u8_t)ip4_addr_cmp(&dipaddr, netif_ip4_addr(netif)); (5) 47 } 48 49 /* 更新ARP緩存表 */ 50 etharp_update_arp_entry(netif, &sipaddr, &(hdr->shwaddr), (6) 51 for_us ? ETHARP_FLAG_TRY_HARD : ETHARP_FLAG_FIND_ONLY); 52 53 /* 更新完畢,根據包的類型處理 */ 54 switch (hdr->opcode) (7) 55 { 56 /* ARP request? */ 57 case PP_HTONS(ARP_REQUEST): (8) 58 /* ARP請求包 */ 59 LWIP_DEBUGF (ETHARP_DEBUG | LWIP_DBG_TRACE, 60 ("etharp_input: incoming ARP request\n")); 61 /* 是請求自己的 */ 62 if (for_us) 63 { 64 /* 做出回應 */ 65 etharp_raw(netif, 66 (struct eth_addr *)netif->hwaddr, &hdr->shwaddr, 67 (struct eth_addr *)netif->hwaddr, netif_ip4_addr(netif), 68 &hdr->shwaddr, &sipaddr, 69 ARP_REPLY); (9) 70 /* 不是給自己的 */ 71 } 72 else if (ip4_addr_isany_val(*netif_ip4_addr(netif))) (10) 73 { 74 LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, 75 ("etharp_input: we are unconfigured, ARP request ignored.\n")); 76 } 77 else (11) 78 { 79 LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, 80 ("etharp_input: ARP request was not for us.\n")); 81 } 82 break; 83 case PP_HTONS(ARP_REPLY): (12) 84 /* 對于ARP應答包*/ 85 LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, 86 ("etharp_input: incoming ARP reply\n")); 87 break; 88 default: 89 LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, 90 ("etharp_input: ARP unknown opcode type %"S16_F"\n", 91 lwip_htons(hdr->opcode))); 92 ETHARP_STATS_INC(etharp.err); (13) 93 break; 94 } 95 /* 釋放內存 */ 96 pbuf_free(p); (14) 97 } ``` (1):判斷ARP包的合法性,已經類型是否為以太網、硬件地址長度是否為ETH_HWADDR_LEN、協議地址長度是否為sizeof(ip4_addr_t)以及協議是否為ARP協議,如果都滿足則表示ARP包合法。 (2):拷貝源IP地址到sipaddr變量中,因為在ARP包中的IP地址字段并不是對齊的,不能直接使用,所以需要拷貝到臨時變量,方便直接操作。 (3):同理拷貝目標IP地址到dipaddr變量中。 (4):看看主機網卡是否配置了IP地址,如果沒有配置,將for_us變量設置為0,表示不是給主機自己的ARP包。 (5):調用ip4_addr_cmp()函數判斷目標IP地址與主機IP地址是否一樣,如果一樣則返回1,將for_us變量設置為1,反之設置為0。 (6):調用etharp_update_arp_entry()函數更新ARP緩存表,這個操作有點特殊,我們稍后講解。 (7):更新完畢,根據包的類型處理,即根據ARP數據包的op字段進行處理。 (8):對于ARP請求包,首先要判斷一下是否是給主機自己的,如果是則要回應,否則就直接丟棄即可。 (9):是請求自己的,調用etharp_raw()函數作出應答。 (10):如果不是給自己的,原因有兩種,一種是網卡自身尚未配置IP地址,這樣子就只打印相關調試信息。 (11):另一種是ARP包中的目標IP地址與主機IP地址不符合,也不用做出回應,直接丟棄即可,并輸出相關調試信息。 (12):對于ARP應答包,理論上應該更新ARP緩存表的,畢竟發出去的ARP請求包得到回應,但是在前面已經更新了緩存表了,此處就不用重復更新了。 (13):對于其他情況,直接返回錯誤代碼。 (14):釋放內存。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看