卸除總和檢查碼工作
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標頭中的總和檢查碼欄位。 迷你埠驅動程式不需要確認總和檢查碼欄位設定為零,而且不需要將此欄位設定為零。
在 MiniportSendNetBufferLists 或 MiniportCoSendNetBufferLists 函式中收到 NET_BUFFER_LIST 結構之後,迷你埠驅動程式通常會執行以下檢查碼處理:
迷你埠驅動程式呼叫 NET_BUFFER_LIST_INFO 巨集,並使用 _Id 為 TcpIpChecksumNetBufferListInfo,以取得 NDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO 結構。
迷你埠驅動程式會在NDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO結構中測試 IsIPv4 和 IsIPv6 旗標。 如果未設定 IsIPv4 和 IsIPv6 旗標,NIC 就不應該在封包上執行任何總和檢查碼作業。
如果已設定 IsIPv4 或 IsIPv6 旗標,迷你埠驅動程式會測試 TcpChecksum、UdpChecksum,以及 IpHeaderChecksum 旗標,以判斷 NIC 應該計算封包的總和檢查碼。
迷你埠驅動程式會將封包傳送至 NIC,由它計算該封包的校驗碼。 如果封包同時具有通道IP標頭和傳輸IP標頭,則支援IP總和檢查碼卸除的NIC只會在通道標頭上執行IP總和檢查碼工作。 TCP/IP 傳輸會在傳輸IP標頭上執行IP總和檢查碼工作。
在指示用於接收封包並執行檢查碼任務的 NET_BUFFER_LIST 結構之前,迷你端口驅動程序會驗證適當的檢查碼並設置相應的 XxxChecksumFailed 或 XxxChecksumSucceeded 旗標於NDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO結構中。
啟用大型傳送卸除時關閉位址總和檢查碼卸除,並不會防止迷你埠驅動程式在 LSO 功能所產生的封包中計算和插入總和檢查碼。 若要在此案例中停用地址校驗和卸載,使用者也必須停用 LSO。