共用方式為


卸除總和檢查碼工作

NDIS 支援在執行時卸載 TCP/IP 總和檢查碼工作。

注意

 檢查碼卸載的帶外(OOB)資料會儲存在 NET_BUFFER_LIST 資訊陣列中。 如需有關 OOB 資料的詳細資訊,請參閱 存取 TCP/IP 卸載 NET_BUFFER_LIST 資訊

在將一個用於執行校驗和工作的封包的 NET_BUFFER_LIST 結構傳遞給迷你埠驅動程式之前,TCP/IP 傳輸會指定與該 NET_BUFFER_LIST 結構相關聯的校驗和資訊。 這項資訊是由 NDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO 結構所指定,這是與NET_BUFFER_LIST結構相關聯的NET_BUFFER_LIST資訊(頻外數據)的一部分。

卸除 TCP 封包的總和檢查碼計算之前,TCP/IP 傳輸會計算 TCP 虛擬標題的補碼總和。 TCP/IP 傳輸會計算虛擬標題中所有欄位的補碼總和,包括來源 IP 位址、目的地 IP 位址、通訊協定,以及 TCP 封包的 TCP 長度。 TCP/IP 傳輸會在 TCP 標頭的 [總和檢查碼] 欄位中輸入虛擬標頭的補碼總和。

TCP/IP 傳輸所提供的偽頭部的一補碼和,使得 NIC 得以提早開始計算傳送封包的實際 TCP 檢查和。 為了計算實際的 TCP 校驗碼,NIC 會計算 TCP 校驗碼的可變部分(針對 TCP 標頭和承載),將此校驗碼新增至 TCP/IP 傳輸所計算之虛擬標頭的補數之和,並計算該校驗碼的 16 位補數。 如需計算這類總和校驗碼的詳細資訊,請參閱 RFC 793 和 RFC 1122。

注意

TCP/IP 傳輸會使用與 TCP 封包相同的步驟,計算 UDP 封包虛擬標頭的補碼總和,並將值儲存在 UDP 標頭的 Checksum 欄位中。

請注意,TCP/IP 傳輸一律可確保封包 IP 標頭中的總和檢查碼欄位設定為零,再將封包傳遞至基礎迷你埠驅動程式。 迷你埠驅動程序應該忽略IP標頭中的總和檢查碼欄位。 迷你埠驅動程式不需要確認總和檢查碼欄位設定為零,而且不需要將此欄位設定為零。

MiniportSendNetBufferListsMiniportCoSendNetBufferLists 函式中收到 NET_BUFFER_LIST 結構之後,迷你埠驅動程式通常會執行以下檢查碼處理:

  1. 迷你埠驅動程式呼叫 NET_BUFFER_LIST_INFO 巨集,並使用 _IdTcpIpChecksumNetBufferListInfo,以取得 NDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO 結構。

  2. 迷你埠驅動程式會在NDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO結構中測試 IsIPv4IsIPv6 旗標。 如果未設定 IsIPv4IsIPv6 旗標,NIC 就不應該在封包上執行任何總和檢查碼作業。

  3. 如果已設定 IsIPv4IsIPv6 旗標,迷你埠驅動程式會測試 TcpChecksumUdpChecksum,以及 IpHeaderChecksum 旗標,以判斷 NIC 應該計算封包的總和檢查碼。

  4. 迷你埠驅動程式會將封包傳送至 NIC,由它計算該封包的校驗碼。 如果封包同時具有通道IP標頭和傳輸IP標頭,則支援IP總和檢查碼卸除的NIC只會在通道標頭上執行IP總和檢查碼工作。 TCP/IP 傳輸會在傳輸IP標頭上執行IP總和檢查碼工作。

在指示用於接收封包並執行檢查碼任務的 NET_BUFFER_LIST 結構之前,迷你端口驅動程序會驗證適當的檢查碼並設置相應的 XxxChecksumFailedXxxChecksumSucceeded 旗標於NDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO結構中。

啟用大型傳送卸除時關閉位址總和檢查碼卸除,並不會防止迷你埠驅動程式在 LSO 功能所產生的封包中計算和插入總和檢查碼。 若要在此案例中停用地址校驗和卸載,使用者也必須停用 LSO。