Go語言ICMP協定:向主機傳送訊息

2020-07-16 10:05:20
ICMP 是用來對網路狀況進行反饋的協定,可以用來偵測網路狀態或檢測網路錯誤。

ICMP 協定介紹

ICMP(Internet Control Message Protocol)因特網控制報文協定。它是 IPv4 協定族中的一個子協定,用於 IP 主機、路由器之間傳遞控制訊息。控制訊息是網路是否暢通、主機是否可達、路由是否可用等網路本身的訊息。這些控制訊息雖然不傳輸使用者資料,但是對於使用者資料的傳遞起著重要的作用。

ICMP 協定是一種面向無連線的協定,用於傳輸出錯報告控制資訊,它是一個非常重要的協定,對於網路安全具有極其重要的意義。ICMP 屬於網路層協定,主要用於在主機與路由器之間傳遞控制資訊,包括報告錯誤、交換受限控制和狀態資訊等。當遇到 IP 資料無法存取目標、IP 路由器無法按當前的傳輸速率轉發封包等情況時,會自動傳送 ICMP 訊息。

ICMP 是 TCP/IP 模型中網路層的重要成員,與 IP 協定、ARP 協定、RARP 協定及 IGMP 協定共同構成 TCP/IP 模型中的網路層。ping 和 tracert 是兩個常用網路管理命令,ping 用來測試網路可達性,tracert 用來顯示到達目的主機的路徑。ping 和 tracert 都利用 ICMP 協定來實現網路功能,它們是把網路協定應用到日常網路管理的典型範例。

從技術角度來說,ICMP 就是一個“錯誤偵測與回報機制”,其目的就是讓我們能夠檢測網路的連線狀況﹐也能確保連線的準確性。當路由器在處理一個封包的過程中發生了意外,可以通過 ICMP 向封包的源端報告有關事件。

其功能主要有:偵測遠端主機是否存在,建立及維護路由資料,重導資料傳送路徑(ICMP 重定向),資料流量控制。ICMP 在溝通之中,主要是透過不同的類別(Type)與程式碼(Code)讓機器來識別不同的連線狀況。

ICMP 協定大致可以分為兩類,一種是查詢報文,一種是差錯報文。其中查詢報文有以下幾種用途:
  • ping 查詢;
  • 子網掩碼查詢(用於無盤工作站在初始化自身的時候初始化子網掩碼);
  • 時間戳查詢(可以用來同步時間)。

而差錯報文則產生在資料傳送發生錯誤的時候。

ICMP訊息型別

ICMP 報告無法傳送資料包的錯誤,且無法幫助對這些錯誤進行疑難排解。例如 IPv4 不能將資料包傳送到目標主機,路由器或目標主機上的 ICMP 會向主機傳送一條“無法到達目標”訊息。

下表為最常見的 ICMP 訊息。

ICMP 訊息型別 用途說明
回顯請求 Ping 工具通過傳送 ICMP 回顯訊息檢查特定節點的 IPv4 連線以排查網路問題,型別值為 0
回顯應答 節點傳送回顯答復訊息響應 ICMP 回顯訊息,型別值為 8
重定向 路由器傳送“重定向”訊息,告訴傳送主機到目標 IPv4 地址更好的路由,型別值為 5
源抑制 路由器傳送“源結束”訊息,告訴傳送主機它們的 IPv4 資料包將被丟棄,因為路由器上發生了擁塞,於是傳送主機將以較低的頻度傳送資料包,型別值為 4
超時 這個訊息有兩種用途。當超過 IP 生存期時向傳送系統發出錯誤資訊;如果分段的 IP 資料包沒有在某種期限內重新組合,這個訊息將通知傳送系統,型別值為 11
無法到達目標 路由器和目標主機傳送“無法到達目標”訊息,通知傳送主機它們的資料無法傳送,型別值為 3

其中無法到達目標訊息中可以細分為一下幾項

無法到達目標訊息 說明
不能存取主機 路由器找不到目標的 IPv4 地址的路由時傳送“不能存取主機”訊息
無法存取協定 目標 IPv4 節點無法將 IPv4 報頭中的“協定”欄位與當前使用的 IPv4 用戶端協定相匹配時會傳送“無法存取協定”訊息
無法存取埠 IPv4 節點在 UDP 報頭中的“目標埠”欄位與使用該 UDP 埠的應用程式相匹配時傳送“無法存取埠”訊息
需要分段但設定了 DF 當必須分段但傳送節點在 IPv4 報頭中設定了“不分段(DF)”標誌時,IPv4 路由器會傳送“需要分段但設定了 DF”訊息

ICMP 協定只是試圖報告錯誤,並對特定的情況提供反饋,但最終並沒有使 IPv4 成為一個可靠的協定。ICMP 訊息是以未確認的 IPv4 資料包傳送的,它們自己也不可靠。

ICMP 的報文格式

ICMP 報文包含在 IP 資料包中,IP 報頭在 ICMP 報文的最前面。一個 ICMP 報文包括 IP 報頭(至少 20 位元組)、ICMP 報頭(至少八位元組)和 ICMP 報文(屬於 ICMP 報文的資料部分)。當 IP 報頭中的協定欄位值為 1 時,就說明這是一個 ICMP 報文。

ICMP 報頭如下圖所示:

ICMP 報頭
圖:ICMP 報頭