6_ICMP

  • ICMP 報文由 IP 層負責傳輸,ICMP 報文的格式以下:算法

類型: 1 byte,用於指定 ICMP 報文的類型.
代碼: 1 byte,用於進一步描述 ICMP 報文爲什麼生成.
檢驗和: 2 bytes,使用的算法與 IP 首部檢驗和算法相同,覆蓋了整個 ICMP 報文.
其餘內容: 不一樣類型和代碼的 ICMP 報文有不一樣的內容.

ICMP 目的不可達

  • 報文格式:shell

    1. 類型: 1 byte,取值爲 3.網絡

    2. 代碼: 1 byte,取值爲 [0,16)spa

    3. 檢驗和: 2 byte,code

    4. 未用位: 4 byte,必須置 0,但當代碼字段的值爲4('須要分片但設置了不分片比特')時,容許路由器把外出接口的 MTU 填在這個32 bit字的低 16 bit中.接口

    5. 引發該 ICMP 差錯報文的 IP 數據包的IP 首部(包括選項)+數據部分的前8字節(正好將 TCP,UDP 的端口號也包含了其中).進程

ICMP 回顯

  • ICMP 回顯請求,應答報文的格式:路由

類型: 1 byte
代碼: 1 byte
檢驗和: 2 byte
標識符: 2 byte
序列號: 2 byte
額外的數據

請求報文的取值:{8;0;算法生成;任意設置;任意設置;...}
應答報文的取值:{0;0;算法生成;不變;不變;不變}

ICMP 地址掩碼請求/應答

  • 用於無盤主機在引導過程當中獲取本身所處子網的子網掩碼.此時分組格式:字符串

ICMP 地址掩碼格式:
類型: 1 byte,
代碼: 1 byte,
檢驗和: 2 byte,
標識符: 2 byte,
序列號: 2 byte,
子網掩碼: 4 byte.
請求格式:{17;0;算法生成;多是隨機生成;多是隨機生成;0}
應答格式:{18;0;算法生成;不變;不變;子網掩碼}

    • 其中應答格式中的'子網掩碼'必須是必須是'收到 ICMP 地址掩碼請求'的網絡接口的子網掩碼,由於一個主機可能具備多個網絡接口,每個網絡接口具備不一樣的掩碼,如:it

# icmpaddrmask 用於向主機名爲 argv[1] 的主機發送 ICMP 地址掩碼請求
sun$ icmpaddrmask sun  # 此時 ICMP 地址掩碼請求會轉交給環回接口,因此返回的是環回接口的地址掩碼.
received mask= ff000000, from 140.252.13.33
sun$ icmpaddrmask localhost # 此時 ICMP 地址掩碼請求直接交給環回接口,
received mask= ff000000, from 127.0.0.

ICMP 時間戳請求/應答

  • 容許主機向另外一個主機查詢當前的時間,下面的'時間戳'是指自午夜(不是 1900-01-01 00:00:00 了)開始計算的毫秒數,協調的統一時間 UTC.此時 ICMP 報文格式:

類型: 1 byte,
代碼: 1 byte,
檢驗和: 2 byte,
標識符: 2 byte,
序列號: 2 byte,
發起時間戳: 4 byte
接受時間戳: 4 byte
傳送時間戳: 4 byte

# 請求格式:
{13;0;算法生成;多是隨機生成;多是隨機生成;發送'ICMP 時間戳請求報文'時的時間戳;0(TODO 不肯定),0 }
# 應答格式:
{14,0,算法生成,不變,不變,不變,接受到'ICMP 時間戳請求報文'時的時間戳,發送'ICMP 時間戳應答報文'時的時間戳};

  • 根據 ICMP 時間戳應答報文的內容與 RTT 調整時間:

var orig; /* 發起時間戳 */
var recv; /* 接受時間戳 */
var xmit; /* 傳送時間戳 */  
var rtt;  /* RTT,往返時間,假設 RTT 的一半用於請求報文的傳輸,另外一半用於應答報文的傳輸 */
則本機時間應該加上 recv-(orig+rtt/2);

若干個概念

  • 日期服務程序,以人們可讀的格式返回當前的時間和日期,是一行 ASCII 字符.

  • 時間服務程序,返回的是一個 32 bit 的二制進數值,表示自 UTC,1900年1月1日午夜起算的秒數

  • NTP,採用先進的技術來保證 LAN 或 WAN 上的一組主機的時鐘偏差在毫秒級之內.

BSD 系統對 ICMP 報文的處理

  • 僅看成一個參考.對處理方法的解釋:

    • 若處理方法指明爲'用戶進程',則報文就被傳送到全部在內核中登記的用戶進程,以讀取收到的 ICMP 報文.若是不存在任何這樣的用戶進程,那麼報文就悄悄地被丟棄

    • 若處理方法指明爲'內核',則 ICMP 報文就由內核來處理,在處理完畢以後,內核會將該 ICMP 報文拷貝給'感興趣'的用戶進程(即已經在內核中登記的用戶進程)

    • 標明的是引號內的一串字符,那麼它就是對應的 Unix 差錯,即 errno 的字符串描述.如當內核收到類型爲3,代碼爲3的 ICMP 差錯報文時,內核會根據差錯報文中帶有的端口號來找到引發差錯的用戶進程,而後讓該用戶進程中的 errno 變量取值爲'鏈接被拒絕'.

本站公眾號
   歡迎關注本站公眾號,獲取更多信息