TCP/IP

TCP 檢驗和 (TCP Checksum)

TCP 三向交握 (Three-way Handshake) 一文中,
說明了 TCP 建立連線的方式,並提及了 Segment (區段) 的觀念。
 
TCP 使用 錯誤控制 (Error Control) 機制,
確保了傳輸的可靠性 (reliable),
其中最常見的是: 檢驗和 (checksum)、確認 (acknowledgement)、逾時 (time-out)。
 
 
本篇將說明 TCP Checksum 的運作方式。
 


 

檢驗和 (Checksum)

檢驗和 (Checksum),提供 傳送方 與 接收方 一種計算方式,
用來檢查 區段 (segment) 是否受損。
 
發送方:
欲發送 TCP 區段前,利用此計算方式 算出 Checksum 值,
並置於 Checksum 欄位。
 
接收方:
將收到的區段,透過相同的計算方式算出 Checksum 值。
並與收到 TCP 區段的 Checksum 欄位值做比較,
若兩者不相等,目的端會丟棄此區段,並視同區段遺失
 

TCP-Header-Format (Checksum)
TCP 表頭格式
 


 

虛擬表頭 (Pseudo-Header) — IPv4

在說明 計算方式 之前,得先說說 虛擬表頭 (Pseudo-Header)!
 
如上圖 (TCP 表頭格式),TCP 本身沒有關於位址的訊息,
這可能造成 區段 (segment) 被 錯誤的路由 (misrouted)。
 
因此,需提供足夠的資訊,讓 checksum 可檢測路由錯誤,
這些資訊就是 — 虛擬表頭 (Pseudo-Header) 啦!
總共有 12 個位元組 (octet) 也就是 96 (12*8) 位元。
 
之所以稱 虛擬 (Pseudo)
是因為這僅供 checksum 計算使用,並不實際傳送。
(位址欄位來自 IP 表頭)
 
pseudo-header-ipv4
 

  • 來源位址 (Source Address):
    32 位元的來源 IPv4 位址
  • 目的位址 (Destination Address):
    32 位元的目的 IPv4 位址
  • Zero:
    顧名思義 (00000000)
  • PTCL:
    通訊協定 (protocol) 的縮寫,
    用來指示使用的 通訊協定 的代號,
    TCP 為 6,UDP 為 17。
  • TCP Length:
    是 TCP Segment 的長度 (表頭+資料),
    並且它不包含虛擬表頭的 12 個位元組。

 


 

虛擬表頭 (Pseudo-Header) — IPv6

當然啦,若使用的不是 32 位元的 IPv4 位址,
而是 128 位元的 IPv6 位址,虛擬表頭 也會有所改變。
 
pseudo-header-ipv6
 

  • 來源位址 (Source Address) 與 目的位址 (Destination Address):
    不再是 IPv4 的 32 位元 (4 位元組),
    而是 IPv6 的 128 位元 (16 位元組)
  • Zero:
    顧名思義 (00000000 00000000 00000000)
    (3 位元組)
  • PTCL:
    一樣,TCP 為 6,UDP 為 17。
    (1 位元組)
  • TCP Length:
    是 TCP Segment 的長度 (表頭+資料),
    並且它不包含虛擬表頭的 40 個位元組。
    (4 位元組)

 

TCP/IPv4 虛擬表頭,為 12 個位元組 (octet),
TCP/IPv6 虛擬表頭,為 40 個位元組 (16+16+3+1+4)。

 


 

計算方式 — 發送方

  1. 若為 發送方,必須先 清除 Checksum 欄位,以產生 Checksum 值。
  2. 將欲計算檢驗和的相鄰位元組,配對為 16-bit 整數,
    包含 虛擬表頭 (Pseudo-Header)、TCP 區段 (表頭+資料),
    當然也包含 Checksum 欄位 (發送方會先清空),
    若資料長度為奇數,則暫時填補 1 個全部為 0 的位元組。
  3. 形成這些 16-bit 整數的 1 的補數和 (1’s complement sum)
  4. 將此 『 1 的補數和 』經過 『 1 的補數 』運算後,
    放入 Checksum 欄位中。

 
簡單說就是:

The checksum field is the 16 bit one’s complement of the
one’s complement sum of all 16 bit words in the header and text.

 


 

計算方式 — 接收方

接收方發送方計算方式如出一徹,
唯一不同在於,不需清除收到的 Checksum 欄位 (因為要透過它來檢查 😅),
算出來的 『1 的補數和』 ,若為 1111 1111 … 1111,
或是 Checksum 值,為 0000 0000 … 0000,
即表示驗證成功,反之。
 
至於,為什麼算出來的值,會是 0000..?
 
假設:
發送方 經過 步驟『1』、『2』、『3』:
利用 『 1 的補數和 』算出包含 虛擬表頭 (Pseudo-Header)、TCP 區段 (表頭+資料),
其值為: 『 0111 』(實際上,當然不是 4 位元,僅為理解用)。
 
TCP 區段 (TCP Segment):
checksum-ex-1
 
接著,經由 步驟『4』:
經過 『 1 的補數 』運算後,
算出 Checksum 欄位為: 『 1000 』。
 


 
如果區段沒有問題,那 接收方 經過 『1』、『2』、『3』步驟,
所算出的 1 的補數和 就會為: 『 0111 』+『 1000 』= 『 1111 』,
 
最後,經由 步驟『4』:
經過 『 1 的補數 』運算 『 1111 』後,
當然就是: 『 0000 』啦 !
 
 

作者: 鄭中勝
喜愛音樂,但不知為何總在打程式 ? 期許能重新審視、整理自身所學,幫助有需要的人。

發表迴響