TCP/IP 筆記 - ICMPv4和ICMPv6 : Internet控制報文協議


ICMP是一種面向無連接的協議,負責傳遞可能需要注意的差錯和控制報文,差錯指示通信網絡是否存在錯誤(如目的主機無法到達、IP路由器無法正常傳輸數據包等。注意,路由器緩沖區溢出導致的丟包不包括在ICMP響應范圍內,在TCP負責范圍)。

ICMPv4和ICMPv6分別指用於IPv4和IPv6的ICMP版本。在IPv4中,協議字段值為1表示該報文攜帶了ICMPv4;在IPv6中,ICMPv6報文位於擴展頭部里,ICMPv6擴展頭部上一個頭部包含了值為58的"下一個頭部"字段。

ICMP報文

所有ICMP報文都以8位的類型(Type)和代碼(Code)字段開始,其后跟隨的16位校驗和(Checksum)字段涵蓋整個報文。

類型字段用於確定特定的報文,ICMPv4和ICMPv6的該字段值並不相同;代碼字段進一步肯定報文的含義,ICMPv4和ICMPv6的該字段值並不相同;校驗和字段用於確定報文信息的正確性。

ICMP報文可分為兩類:有關IP數據報傳遞的ICMP報文(差錯報文)和信息采集和配置的ICMP報文(查詢或者信息類報文)。

由類型字段決定的ICMPv4報文類型

(*)標記的類型是最常見的,(+)標記的可能包含[RFC4884]擴展對象,E表示差錯報文,I表示查詢/信息類報文。

ICMPv4報文類型使用的代碼

由類型字段決定的ICMPv6報文類型:差錯報文的類型從0-127,信息類報文類型為128-255

ICMPv6報文類型使用的代碼

一般來說,對於傳入的ICMP信息,查詢或信息類將被操作系統自動處理,差錯類報文傳遞給用戶進程或傳輸層協議(除去重定向報文和目的地不可達,前者導致主機路由表的自動更新,后者用於路徑MTU發現機制)。

傳入的ICMPv6報文處理規則如下:

  1. 未知的ICMPv6差錯報文必須傳遞給上層產生差錯報文的進程;

  2. 未知的ICMPv6信息類報文被丟棄;

  3. ICMPv6差錯報文將會盡可能多地包含到差錯的原始(違規)IPv6報文,最終的差錯報文大小不能超過最小的IPv6 MTU(1280字節);

  4. 在處理ICMPv6差錯報文時,需要提取原始或違規數據包中的上層協議類型,用於選擇適當的上層進程;

  5. 存在處理差錯的特殊規則;

  6. IPv6節點必須限制它發生ICMPv6差錯報文的速率。

查詢/消息類報文

由於某些ICMP的功能已經被其他特殊目的的協議代替,保存下來的廣泛使用的ICMP查詢/信息類報文是回顯請求/應答報文(常用的"ping"),以及路由器發現報文。

回顯請求/應答相對簡單,收到回顯請求之后,ICMP的實現要求將任何收到的數據返回給發送者。其報文結構如下:

發送主機利用標識符來分離返回的應答(如多個ping同時允許的時候,用於區分返回的應答)。

當一個ping實例運行時,序列號從0開始,每發送一個回顯請求則加1.

路由器發現則較為復雜,也就是與移動IP一起使用的那個。其主要目的是讓一台主機學習到它所在的本地子網中所有路由器,從而選擇一台作為默認路由器,也用於發現那些願意充當移動IP代理的路由器。

地址數給出報文中路由地址塊的個數,每個塊包含一個IPv4地址及相應的優先水平(優先水平是一個32位的有符號二進制補碼整數,其值越大代表優先級越高。默認的優先水平是0,特殊值0x80000000表示這個地址不應該用作有效的默認路由);

地址條目大小給出每個塊的32位字數;

生命周期給出地址列表被認為有效的秒數;

序列號字段給出了自從初始化之后代理產生的這種擴展的個數;

注冊字段給出了發送 代理願意接受MIPv4注冊的最大秒數(0xFFFF表示無窮大);

那些字母的含義:R(為MIP服務所需的注冊)、B(代理太忙無法接受注冊)、H(代理願意充當本地代理)、F(代理願意充當外地代理)、M(支持最小封裝格式)、G(代理支持封裝數據報的GRE隧道)、r(保留零)、T(支持反向隧道)、U(支持UDP的隧道)、X(支持撤銷注冊)、I(外地代理支持區域注冊)。

差錯報文

ICMP差錯報文不會對以下報文進行響應:

  1. 另一個ICMP差錯報文;

  2. 頭部損壞的數據報;

  3. IP層的廣播/組播數據報;

  4. 封裝在鏈路層廣播或者組播幀中的數據報;

  5. 無效或者網絡為零的源地址數據報;

  6. 或除第一個之外的其他分片。

限制生成ICMP差錯報文的原因是限制生成廣播風暴。在[RFC4443]中,推薦采用令牌桶(token bucket)方法來限制ICMP報文速率。過程如下(一令牌大小為一字節):

  1. 假設"桶"里保存了最大數量"B"的"令牌",如果"令牌"到達時"桶"滿了,則"令牌"被丟棄;

  2. 當一個N字節的數據包達到,如果"桶"中多於N個"令牌",則刪除N個"令牌",且數據包被發送到網絡;如果"桶"中少於N個"令牌",則不刪除"令牌",且認為這個數據包在流量限制之外。

ICMPv4到ICMPv6的轉換只有回顯請求和回顯應答報文被轉換,為了執行這個轉換,類型值(8和0)分別被轉換到值128和129。在轉換之后,計算並應用ICMPv6的偽頭部校驗和。當轉換ICMPv4差錯報文時,只有下面的差錯報文被轉換了:目的不可達(類型3),超時(類型11),參數問題(類型12)。

ICMPv6到ICMPv4的轉換回顯請求(類型128)和回顯應答(類型129)報文被分別轉換到ICMPv4回顯請求(類型8)和回顯應答(類型0),更新校驗和以體現類型值變化和缺少為頭部計算,其他信息類報文將被丟棄。

IPv6鄰居發現

IPv6中的鄰居發現協議(NDP或者ND)中兩個主要部分是:鄰居請求/通告(NS/NR),在網絡和鏈路層地址之間提供類似於ARP的映射功能;路由器的請求/通告(RS/RA),提供的功能包括路由器發現、移動IP代理發現、重定向,以及對一些自動配置的支持。

ND報文就是ICMPv6報文,只是發送時IPv6的跳數限制字段值被設置為255。接收者通過驗證進來的ND報文有這個值,以防止被非本鏈路上的發送者嘗試發送假冒本地ICMPv6欺騙。

路由器請求/通告

RS報文結構很簡單,用於請求鏈路上的路由器發送RA報文,RS報文被發送到所有路由器組播地址ff02::2。

RA報文結構略為復雜,由路由器發送到所有節點的組播地址ff02::1,或者發送到請求主機的單播地址(為響應某個請求)。

當前跳數限制字段指定主機發送IPv6數據報的默認跳數限制;

M(托管)字段表明本地IPv6地址分配是由有狀態的配置來處理的,主機應避免使用無狀態的自動配置;

O(其他)字段標識其他有狀態的信息使用一個有狀態的配置機制;

H(本地代理)字段標識發送路由器願意充當一個移動IPv6節點的本地代理;

Pref(優先級)字段給出將報文發送者作為一個默認路由器來使用的優先級層次(01,高;00,中,默認;11,低;10:保留,未使用);

P(代理)標志,當和實驗性質的ND代理工具配合使用時被設置,為IPv6提供一個類似代理ARP的功能;

路由器生命周期字段表示發送路由器可以作為默認下一跳的時間,以秒為單位,可為0;

可達時間字段給出一個節點到達另一個節點所需的毫秒數;

重傳計時器字段規定主機延遲發送連續ND報文的時間,單位毫秒。

鄰居請求/通告 

ICMPv6中的鄰居請求(NS)報文有效的取代了IPv4中的ARP請求報文。其主要目的是將IPv6地址轉換為鏈路層地址,也被用於檢測附近的節點是否可達,它們是否可以雙向到達。

NS報文包含發送者想設法學習的鏈路層地址對應的IPv6地址,該報文可能包含源鏈路層地址選項,當請求是被發送到組播地址時,該選項必須包含在使用鏈路層尋址的網絡中,對於單筆請求而言,該選項應該被包含。如果報文的發送者使用未指定的地址作為源地址,則不應該包括該選項。

NA報文要么作為NS報文響應被發送;要么當一個節點的IPv6地址變化時被異步發送。要么被發送到請求節點的單播地址;要么當請求節點使用未指定的地址作為源地址時,被發送到所有節點的組播地址。

R表示發送者是一個路由器;S表示通告是為了響應一個請求;O表示該報文的內容應覆蓋其他緩存的地址映射;目標地址字段包含報文發送者的IPv6地址。

鄰居不可達檢測

鄰居不可達檢測用於管理鄰居緩存,鄰居緩存是個概念上的數據結構,用於保存IPv6到鏈路層地址的映射信息以及針對映射狀態的信息。維護規程如下:

五個狀態:INCOMPLETE,REACHABLE,STALE,DELAY,PROBE。

大致過程如下:

  1. 初始狀態為INCOMPLATE或STALE;

  2. 當一個IPv6節點有一個單播數據報需要發送到目的地時,它會檢查其目標緩存,查看對應於目的地的條目是否存在;

  3. 如果存在且目的地是在鏈路上的,再查看鄰居緩存,確定鄰居狀態是否為REACHABLE;

  4. 如果是,使用直接交付方式發生數據報。如果沒有鄰居緩存條目,但目標似乎是在鏈路上,NUD會進入INCOMPLETE狀態,並發送一個NS報文;

  5. 成功收到一個請求NA報文便可以確定該節點是可大的,條目進入REACHABLE狀態。

STALE狀態對應於目前還未確認的無效條目。當一個條目之前是REACHABLE狀態,但已有一段時間未更新或者收到主動報文時,便進入STALE。

DELAY和PROBE是臨時狀態。DELAY用於當一個數據包已經被發送,但ND目前尚無證據表明可能是到達的情況,該狀態給上層協議一個機會來提供更多的證據。如果在DELAY_FIRST_PROBE_TIME后仍未收到證據,則進入PROBE。

PROBE狀態ND會定期發送NS報文(每RetransTimer毫秒,常數默認值RETRANS_TIMER等於1000),如果在發送MAX_UNICAST_SOLICIT(預設為3)個NS報文后還未收到任何證據,則刪除條目。

安全鄰居發現

安全鄰居發現(SEND)是一組特殊的增強功能,旨在為ND報文提供額外的安全性。SEND大致如下:

  1. 每個具備SEND的路由器有一個證書或者密碼認證,它可以用來證明一台主機的身份;

  2. 每個主機配備一個信任錨 -- 配置信息可以用來驗證證書的有效性;

  3. 每個節點在配置它將使用的IPv6地址時,將會生成一個公鑰/私鑰對。

SEND使用完全不同類型的稱為密碼生成地址(CGA)的IPv6地址。將一個64位的子網前綴和一個特殊構造的接口標識符相"或",便生成一個IPv6 CGA。其中CGA接口標識符是通過Hash1安全散列函數計算出來的,它的輸入是節點的公鑰和一個特殊的CGA參數數據結構。

用來計算CGA的SEND方法如圖:

偽隨機序列字段初始化一個隨機值,碰撞計數字段初始化為0,擴展字段供之后使用。

Hash2值必須有(16*Sec)個初始,Sec是一個3位的參數,IANA為Sec值維護一個注冊表[SI]。

SEND定義了請求和通告報文用來幫助主機確定構成一個證書路徑的證書,被主機用來驗證路由器通告的真實性。

ND(鄰居發現)報文可能包含零個或多個選項,一些選項可以出現多次。所有的ND選項以8位類型和8位長度字段開始,支持長度可變的選項,最大到255字節。

ICMPv6鄰居發現選項

選項列表:

下面是各個選項的格式圖:

源/目標鏈路層地址選項(類型1,2),源(類型1)和目標(類型2)鏈路層地址選項。長度字段值給出了整個選項的長度,包括地址,以8字節為單位。

前綴信息選項(類型3),前綴長度字段給出在配置中被視為有效的前綴字段中的位數(多達128位);

L位字段是“在鏈路上”的標志,並表示所提供的前綴是能用於在鏈路上判定的。如果沒有設置,它對在鏈路上判定的使用沒有做任何聲明;

A位字段就是“自主自動配置”標志,並表示所提供的前綴可用於自動配置;

R位字段設置為1表示前綴字段包含發送路由器的整個全局IPv6地址,而不只是將前綴中的剩余位設置為0或者是它的本地鏈路地址;

有效生命周期和首選生命周期字段分別表示前綴能被用於在鏈路上判定和自動地址配置的秒數,0xFFFFFFFF表示無窮大。

重定向頭部選項(類型4),重定向頭部選項被用於包含一份導致生成重定向報文的原始(“違規”)IPv6數據報。

MTU選項(類型5),這個報文保留了32個比特位來存儲MTU,支持非常大的MTU。此報文本來是用於診斷網絡,但已被用於路徑MTU發現。

通告間隔選項(類型7),通告間隔選項給出定期路由器通告報文間的時間。通告間隔字段定義了此報文到達網絡上的發送者所發送的RA報文傳輸間的最大毫秒數。

本地代理信息選項(類型8),本地代理優先級字段是一個16位無符號證書,用於幫助移動節點預定通過"本地代理地址發現應答"報文提供給它的地址,值越大表示發送路由器作為一個本地代理的優先級程度越大,起始路由器的優先級被認為是0(最低)。本地代理生命周期字段也是16位無符號證書,指定該報文的發送者應考慮作為本地代理的秒數。

源和目標地址列表選項(類型9,10),這些被用來支持IND,並提供了一個節點的IPv6地址的列表。只能包含用來發送報文的接口的地址。

CGA選項(類型11),被用來和SEND一起攜帶CGA參數,這些參數是檢驗器執行CGA驗證和簽名驗證所必需的。

RSA簽名選項(類型12),被用來和SEND一起攜帶校驗器能夠使用的RSA簽名,將它和CGA參數一起確定發送系統是否擁有與CGA公鑰相關的私鑰。密鑰散列字段包含構建簽名所使用的公鑰經SHA-1散列后其結果的高128位;數字簽名字段包含一個機遇下面這些值的標准化簽名:SEND的CGA報文類型標簽,源IP和目的IP地址,ICMPv6頭部的開始32位字(類型、代碼和校驗和字段),ND協議的報文頭和選項。

時間戳選項(類型13),選項給出了發送系統知曉的當天的當前時間,時間戳字段記錄了自1970年1月1目00:00UTC以來的秒。

隨機數選項(類型14),用於防范潛在的針對SEND的重放攻擊,數值長度至少為6個長度。

信任錨選項(類型15),該選項包含一個證書路徑的名稱(根),與SEND一起被主機用來驗證RA報文的真實性。類型字段標識所使用的名稱類型,當前定義的兩個值:1,DERX.502 名稱;2,全限定域名稱(FQDN)。名稱字段采用名稱類型字段定義的格式給出信任錨的名稱。

證書選項(類型16),選項保存了和SEND一起使用的單獨證書,用以提供證書路徑。證書類型字段標識所使用的證書的類型。目前值定義了一個值:1,X.509v3證書。

IP地址/前綴選項(類型17),和FMIPv6報文一起使用。選項代碼字段值表示哪種類型的地址被編碼了:1. 舊的移交地址;2. 新的移交地址;3. 新訪問路由器的IPv6地址;4. NAR的前綴。前綴長度字段給出了IPv6地址字段中有效前導位個數。

鏈路層地址選項(類型19),和FMIPv6報文一起使用,選項代碼字段值表示相關的鏈路層地址字段值是如何解釋的:0. 通配符,即附近所有的AP都要求解析;1. 新的AP地址;2. 移動節點的地址;3. 新訪問路由器的地址;4. RtSolPr/PrRtAdv報文的源地址;5. 地址是當前路由器的;6. 對應到這個地址的AP沒有可用的前綴信息;7. 編址的AP沒有可用的快速切換。鏈路層地址字段包含由選項代碼字段指定的地址。

鄰居通告確認選項(類型20),選項代碼字段值是0,狀態字段表示對主動鄰居報文的處置。定義了如下值:1. 新移交地址(NCoA)是無效的(執行地址配置);2. NCoA是無效的(采用IP地址選項中提供的NCoA);3. NCoA是無效的(使用NAR第地址來代替NCoA);4. 之前提供的移交地址(PCoA)(沒有發生綁定更新);128. 無法識別的鏈路層地址。

路由信息選項(類型24),表示通過一個特定路由器能夠到達哪些不在鏈路上的前綴。前綴長度字段給出前綴字段中的有效先導位的個數。前綴字段標識個包含的前綴相關聯的路由器相對於其他路由器的優先級,如果值為2,則選項必須被忽略。路由生命周期字段給出了前綴被認為有效的秒數,所有值都為1表示無窮大。

遞歸DNS服務器選項(類型25),能夠通過提供一個或多個DNS服務器的地址來增強無狀態配置。生命周期字段給出了列表中的DNS服務器被認為是有效的時間長度,單位秒,所有值為1表示無窮大。

路由器通告擴展標志選項(類型26),長度字段目前被定義為1,知道后續的位被分配。

切換密鑰請求選項(類型27),它使用SEND保護信令信息的安全。填充長度字段給出在選項尾端用0填充的字節個數。算法類型字段表示用於計算認證者的算法。切換密鑰加密公鑰字段使用和CGA選項相同的格式解密了FMIPv6 CGA公鑰。填充字段包含了值為0的字節以保證選項的長度是9字節的倍數。

切換密鑰應答選項(類型28),它使用SEND保護信令信息的安全。密鑰生命周期字段給出了切換密鑰有效的秒數(默認是HK-LIFETIME或者43200s)。加密的切換密鑰字段保存了一個對稱密鑰,是經過移動節點的切換密鑰加密過的。加密格式是RSAES-PKCS1-v1_5。

NDS搜索列表選項(類型31),用來表示一個域名擴展到被添加到一台主機可能發起的DNS查詢中。生命周期字段標識從報文被發送的時間開始,域名搜索列表被認為是有效的時長。域名搜索列表包含一個域名擴展的列表(未壓縮),作為從部分字符串構建的GQDN的默認形式。

ICMP相關攻擊

設計ICMP的攻擊主要分為3類:泛洪、炸彈、信息泄露。泛洪指的是生成大量流量,導致針對一台或者多台計算機的有效DoS攻擊。炸彈指的是發送經過特殊構造的報文,能導致IP或者ICMP的處理機制奔潰或終止。信息泄露本身並不會造成危害,但能夠幫助其他攻擊方法避免浪費時間或者被發現。

早期有一種稱為Smurf的攻擊,就是使用目的地址為廣播地址的ICMPv4,導致了大量計算機做出響應。

采用ICMPv4的回顯請求/應答報文(ping),有可能以這樣一種方式來構建數據包分片,攻擊如果涉及到IPv4頭中的分片偏移字段,則將導致IPv4分片重組路由器的錯誤,稱為淚滴攻擊。

ICMP目的不可達報文可造成現有連接(如TCP)的拒絕服務,這些攻擊有時被稱為Smack或Bloop攻擊。

還有一種涉及到修改PTB報文的攻擊,可強制終端TCP運行時使用非常小的數據包,從而導致性能低下。

  

參考:

《TCP IP 詳解卷1:協議》

RFC官方文檔


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM