<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>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                以太網是有自己獨立的尋址方式(MAC地址),而對于TCP/IP的上層協議(如TCP協議、IP協議),它們是以IP地址作為網絡的標識,如果沒有IP地址則無法進行收發數據。當數據通過網卡中接收回來的時候,LwIP內核就需要將數據進行分解,如果是IP數據報則遞交給IP協議去處理,如果是ARP數據包則交由ARP協議去處理。 LwIP中數據包從網卡接收的函數是ethernetif\_input(),從第9章我們可以知道,真正讓LwIP內核去處理接收到的數據包是ethernet\_input()函數,這兩個函數是不一樣的,名字稍微有點區別,LwIP就是在這個函數中處理不同的數據包類型,其源碼具體見代碼清單 10?8。 ``` 1 err_t 2 ethernet_input(struct pbuf *p, struct netif *netif) 3 { 4 struct eth_hdr *ethhdr; 5 u16_t type; 6 7 #if LWIP_ARP || ETHARP_SUPPORT_VLAN || LWIP_IPV6 8 9 u16_t next_hdr_offset = SIZEOF_ETH_HDR; 10 11 #endif 12 13 LWIP_ASSERT_CORE_LOCKED(); 14 15 //校驗數據長度 16 if (p->len <= SIZEOF_ETH_HDR) 17 { 18 ETHARP_STATS_INC(etharp.proterr); 19 ETHARP_STATS_INC(etharp.drop); 20 MIB2_STATS_NETIF_INC(netif, ifinerrors); 21 goto free_and_return; 22 } 23 24 if (p->if_idx == NETIF_NO_INDEX) 25 { 26 p->if_idx = netif_get_index(netif); 27 } 28 29 /* ethhdr指針指向以太網幀頭部,并且強制轉換成eth_hdr結構 */ 30 ethhdr = (struct eth_hdr *)p->payload; (1) 31 32 type = ethhdr->type; 33 34 if (ethhdr->dest.addr[0] & 1) 35 { 36 /* 這可能是多播或廣播數據包 */ 37 if (ethhdr->dest.addr[0] == LL_IP4_MULTICAST_ADDR_0) 38 { 39 if ((ethhdr->dest.addr[1] == LL_IP4_MULTICAST_ADDR_1) && 40 (ethhdr->dest.addr[2] == LL_IP4_MULTICAST_ADDR_2)) 41 { 42 /* 將pbuf標記為鏈路層多播 */ 43 p->flags |= PBUF_FLAG_LLMCAST; (2) 44 } 45 } 46 47 else if (eth_addr_cmp(&ethhdr->dest, &ethbroadcast)) 48 { 49 /* 將pbuf標記為鏈路層廣播 */ 50 p->flags |= PBUF_FLAG_LLBCAST; (3) 51 } 52 } 53 54 switch (type) 55 { 56 /* 如果是IP數據報 */ 57 case PP_HTONS(ETHTYPE_IP): 58 if (!(netif->flags & NETIF_FLAG_ETHARP)) 59 { 60 goto free_and_return; 61 } 62 /* 跳過以太網首部 */ 63 if (pbuf_remove_header(p, next_hdr_offset)) (4) 64 { 65 goto free_and_return; 66 } 67 else 68 { 69 /* 傳遞到IP協議去處理 */ 70 ip4_input(p, netif); (5) 71 } 72 break; 73 74 //對于是ARP包 75 case PP_HTONS(ETHTYPE_ARP): 76 if (!(netif->flags & NETIF_FLAG_ETHARP)) 77 { 78 goto free_and_return; 79 } 80 /* 跳過以太網首部 */ 81 if (pbuf_remove_header(p, next_hdr_offset)) (6) 82 { 83 ETHARP_STATS_INC(etharp.lenerr); 84 ETHARP_STATS_INC(etharp.drop); 85 goto free_and_return; 86 } 87 else 88 { 89 /*傳遞到ARP協議處理 */ 90 etharp_input(p, netif); (7) 91 } 92 break; 93 94 //如果支持PPPOE 95 #if PPPOE_SUPPORT 96 case PP_HTONS(ETHTYPE_PPPOEDISC): 97 pppoe_disc_input(netif, p); 98 break; 99 100 case PP_HTONS(ETHTYPE_PPPOE): 101 pppoe_data_input(netif, p); 102 break; 103 #endif /* PPPOE_SUPPORT */ 104 105 //如果支持ipv6 106 #if LWIP_IPV6 107 case PP_HTONS(ETHTYPE_IPV6): /* IPv6 */ 108 /* skip Ethernet header */ 109 if ((p->len < next_hdr_offset) || 110 pbuf_remove_header(p, next_hdr_offset)) 111 { 112 goto free_and_return; 113 } 114 else 115 { 116 /* pass to IPv6 layer */ 117 ip6_input(p, netif); 118 } 119 break; 120 #endif /* LWIP_IPV6 */ 121 122 default: 123 #ifdef LWIP_HOOK_UNKNOWN_ETH_PROTOCOL 124 if (LWIP_HOOK_UNKNOWN_ETH_PROTOCOL(p, netif) == ERR_OK) 125 { 126 break; 127 } 128 #endif 129 ETHARP_STATS_INC(etharp.proterr); 130 ETHARP_STATS_INC(etharp.drop); 131 MIB2_STATS_NETIF_INC(netif, ifinunknownprotos); 132 goto free_and_return; 133 } 134 135 return ERR_OK; 136 137 free_and_return: 138 pbuf_free(p); 139 return ERR_OK; 140 } ``` (1):ethhdr指針指向以太網幀首部,并且強制轉換成eth_hdr結構,這是為了方便對以太網幀首部進行操作。 (2):如果目標IP地址的第一個字節的bit0是1,那么有可能是多播或者是廣播數據包,所以,還需要進行判斷,如果是多播的,就將pbuf標記為鏈路層多播。 (3):如果是廣播的,就將pbuf標記為鏈路層廣播。 (4):如果數據包是ETHTYPE_IP類型,則調用pbuf_remove_header()函數跳過以太網幀首部,方便對數據進行操作。 (5):除去以太網幀首部成功,調用ip4_input()函數將數據包遞交到IP協議去處理,對于IP層的處理,我們在后面的章節中講解。 (6):跳過以太網幀首部。 (7):除去以太網幀首部成功,調用etharp_input ()函數將數據包遞交到ARP協議去處理。
                  <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>

                              哎呀哎呀视频在线观看