<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之旅 廣告
                etharp\_output()函數被IP層的ip4\_output()函數調用,IP層傳遞一個數據包到ARP中,etharp\_output()會根據數據包的目標IP地址選擇不同的處理,其源碼具體見代碼清單 10?11。 ``` 1 const struct eth_addr ethbroadcast = 2 {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}}; 3 4 const struct eth_addr ethzero = {{0, 0, 0, 0, 0, 0}}; 5 6 /** 24位IANA IPv4多播OUI為01-00-5e: */ 7 #define LL_IP4_MULTICAST_ADDR_0 0x01 8 #define LL_IP4_MULTICAST_ADDR_1 0x00 9 #define LL_IP4_MULTICAST_ADDR_2 0x5e 10 11 err_t etharp_output 12 (struct netif *netif, struct pbuf *q, const ip4_addr_t *ipaddr) 13 { 14 const struct eth_addr *dest; 15 struct eth_addr mcastaddr; 16 const ip4_addr_t *dst_addr = ipaddr; 17 18 LWIP_ASSERT_CORE_LOCKED(); 19 LWIP_ASSERT("netif != NULL", netif != NULL); 20 LWIP_ASSERT("q != NULL", q != NULL); 21 LWIP_ASSERT("ipaddr != NULL", ipaddr != NULL); 22 23 if (ip4_addr_isbroadcast(ipaddr, netif)) 24 { 25 /* 如果是廣播數據包,目標MAC地址設置為FF-FF-FF-FF-FF-FF-FF */ 26 dest = (const struct eth_addr *)&ethbroadcast; (1) 27 /* multicast destination IP address? */ 28 } 29 else if (ip4_addr_ismulticast(ipaddr)) 30 { 31 /* 如果是多播數據包,目標MAC地址設置為多播地址:01-00-5E-XX-XX-XX*/ 32 mcastaddr.addr[0] = LL_IP4_MULTICAST_ADDR_0; 33 mcastaddr.addr[1] = LL_IP4_MULTICAST_ADDR_1; 34 mcastaddr.addr[2] = LL_IP4_MULTICAST_ADDR_2; 35 mcastaddr.addr[3] = ip4_addr2(ipaddr) & 0x7f; 36 mcastaddr.addr[4] = ip4_addr3(ipaddr); 37 mcastaddr.addr[5] = ip4_addr4(ipaddr); 38 39 dest = &mcastaddr; (2) 40 41 } 42 else 43 { 44 /* 如果是單播目標地IP地址 */ 45 netif_addr_idx_t i; 46 /* 判斷目標IP地址是否與主機處于同一子網上, 47 如果不是,則修改IP地址 */ 48 if (!ip4_addr_netcmp(ipaddr, netif_ip4_addr(netif), 49 netif_ip4_netmask(netif)) && 50 !ip4_addr_islinklocal(ipaddr)) (3) 51 { 52 #if LWIP_AUTOIP 53 struct ip_hdr *iphdr = 54 LWIP_ALIGNMENT_CAST(struct ip_hdr *, q->payload); 55 56 if (!ip4_addr_islinklocal(&iphdr->src)) 57 #endif 58 { 59 #ifdef LWIP_HOOK_ETHARP_GET_GW 60 dst_addr = LWIP_HOOK_ETHARP_GET_GW(netif, ipaddr); 61 if (dst_addr == NULL) 62 #endif 63 { 64 /* 判斷一下網關地址是否有效 */ 65 if (!ip4_addr_isany_val(*netif_ip4_gw(netif))) (4) 66 { 67 /* 發送到默認網關,讓網關進行轉發 */ 68 dst_addr = netif_ip4_gw(netif); 69 /* 沒有默認網關可用 */ 70 } 71 else 72 { 73 /* 返回錯誤 */ 74 return ERR_RTE; 75 } 76 } 77 } 78 } 79 /* 遍歷ARP緩存表 */ 80 for (i = 0; i < ARP_TABLE_SIZE; i++) 81 { 82 if ((arp_table[i].state >= ETHARP_STATE_STABLE) && 83 (arp_table[i].netif == netif) && 84 (ip4_addr_cmp(dst_addr, &arp_table[i].ipaddr))) 85 { 86 /* 如果找到目標IP地址對應的表項,直接發送 */ 87 ETHARP_SET_ADDRHINT(netif, i); 88 return etharp_output_to_arp_index(netif, q, i); (5) 89 } 90 } 91 /* 如果沒有找到與目標IP地址對應的ARP表項 */ 92 return etharp_query(netif, dst_addr, q); (6) 93 } 94 95 /* 對于多播、廣播數據包,直接能得到對應的MAC地址,可以進行發送*/ 96 return ethernet_output(netif, q, 97 (struct eth_addr *)(netif->hwaddr), dest, ETHTYPE_IP); (7) 98 } ``` (1):如果是廣播數據包,目標MAC地址設置為FF-FF-FF-FF-FF-FF-FF。 (2):如果是多播數據包,目標MAC地址設置為多播地址:01-00-5E-XX-XX-XX。 此處簡單補充一下單播包、廣播包與多播包的相關知識: 單播包:顧名思義,就是一對一通信,發送的目標主機IP地址是唯一的,就像是人們之間的對話一樣,一個人對另外一個人說話。 多播包:“多播”可以理解為一個人向多個人(但不是在場的所有人)說話,比如在一個大餐廳中,一個人說話只能讓一桌人知道,而其他桌上的人并不知道說了什么。同理的,主機發送的多播包只能讓某些滿足條件的目標主機接收到。 廣播包:而廣播就是類似于用大喇叭進行廣播通知,在場的所有人都能知道。廣播包是讓所有處于同一子網的主機都能接收到數據包。 (3):如果是單播目標地IP地址,首先判斷目標IP地址是否與主機處于同一子網上,如果不是,則修改IP地址,IP地址為網關的IP地址,目的是為了讓網關進行轉發。 (4):判斷一下網關地址是否有效,如果有效,則發送到默認網關,讓網關進行轉發,沒有默認網關可用則返回錯誤代碼。 (5):遍歷ARP緩存表,如果找到目標IP地址對應的表項,調用etharp_output_to_arp_index()函數直接發送,該函數源碼具體見代碼清單 10 12。 (6):如果沒有找到與目標IP地址對應的ARP表項,需要調用etharp_query()函數進行發送,這個函數在稍后講解,具體見10.11.3 小節。 (7):對于多播、廣播數據包,直接能得到對應的MAC地址,可以進行發送。
                  <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>

                              哎呀哎呀视频在线观看