IP的路由過程分析

TCP/IP協議簇是目前互聯網應用最廣的協議棧,談到TCP/IP協議棧就不能不講一講IP路由的問題,因爲在我們使用的網絡通信中幾乎每時每刻都在發生着IP路由的事件……。當你在網絡世界中還是一位新手的時候,你也許認爲設備之間實現IP路由所需的僅僅是一臺設備的IP地址而已,如果你真的這樣認爲那就錯了。每臺設備在進行IP路由的時候除了必需的IP地址外還需要很多其他信息來完成數據的封裝!我將通過以下網絡場景提供的案例一步一步地來分析設備在進行IP路由時將會發生哪些通信事件。




      在這個場景中有兩個網絡,這兩個網絡通過一臺具有兩個以太網接口(F0/0,F0/1)的路由器連接在一起。路由器的這兩個端口和你自己電腦上的RJ-45型號的網卡端口是一樣的,都是內建在路由器中的。現在我們來看一看當位於網絡A的主機A想要和位於網絡B的主機B進行通信時都發生了什麼?

      主機A打開命令提示符(具體方法:開始——運行——cmd),命令提示符(>)後輸入ping 1.1.1.5  當“ping”這個指令被計算機執行的時候,TCP/IP協議棧會調用該協議棧互聯網層的“ICMP”協議封裝“ping 1.1.1.5”這個請求。

ICMP協議封裝如下:
ICMP報頭 (主機A) Ping 1.1.1.5
      Host A(主機A)若要將這個ICMP協議封裝的請求發送給目標主機B(Host B)就必須要使用IP協議來“運輸”該請求。這樣,IP協議這個時候就充當了一個郵差的角色,將ICMP這個數據包寫上發送者(主機A)的IP地址和接收者(主機B)的IP地址,然後就可以根據這個目標地址(主機B的地址)來“投遞”這個數據包了。

IP協議封裝如下:

IP報頭 ICMP報頭 (主機A) Ping 1.1.1.5

      經過IP協議封裝的數據包只是完成了TCP/IP協議簇網絡層上的封裝,接下來要完成的是數據鏈路層的封裝。在進行數據鏈路層的信息封裝之前主機A還需啓動IP路由進程來判斷目標主機B在本地網絡還是在遠程網絡。若主機B在本地網絡,說明主機B和主機A在同一個邏輯子網中,也就是同一個IP網段內。若主機B在遠程網絡則說明主機B與主機A不在同一個網段內,比如本例中,主機A位於網絡A而主機B位於網絡B。顯而易見,在本例的網絡場景中主機A會判斷出主機B位於遠程網絡。那麼問題是主機A是如何做出判斷的呢?
      首先主機A將自己的IP地址和子網掩碼作“與運算”。所謂與運算就是無論是二進制的“0”和“1”相與還是二進制的“0”和“0”相與,得出的結果都爲“0”,而只有二進制“1”和“1”相與得出的結果爲“1”。比如本例中,主機A的IP地址爲192.168.0.5,將這個IP地址轉換爲二進制就是:11000000 10101000 00000000 00000101
      主機A的子網掩碼爲255.255.255.0,將該掩碼轉換爲二進制就是:11111111 11111111 11111111 00000000 將主機A二進制形式的IP地址和子網掩碼作“與運算”的結果是:  11000000 10101000 00000000 00000000
      爲了方便查看將這個“與運算”的結果再轉換爲點分十進制的數就是:192.168.0.0
      這樣主機A就通過“與運算”完成了IP路由判斷的第一步。接下來的第二步是將目標主機(主機B)的IP地址與發送方(主機A)的子網掩碼作“與運算”,比如本例中,主機B的IP地址爲1.1.1.5,將這個IP地址轉換爲二進制就是:00000001 00000001 00000001 00000101
      主機A的子網掩碼爲255.255.255.0將該掩碼轉換爲二進制就是:11111111 11111111 11111111 00000000 將以上兩組二進制的數進行“與運算”的結果是:00000001 00000001 00000001 00000000 將這個“與運算”的結果轉換爲點分十進制的數就是:1.1.1.0 這樣我們就得到了兩組“與運算”的結果,分別是:192.168.0.0和1.1.1.0
      對於主機A來說,經過這樣一番“與運算”後,如果兩個“與運算”結果相同,則說明目標主機B和自己在同一個網絡內,即目標主機B在本地網絡。相反地,對於主機A來說,經過這樣一番“與運算”後,如果兩個“與運算”結果不同,則說明目標主機B和自己不在同一個網絡內,即目標主機B在遠程網絡。在本例中,很顯然目標主機B對於發送方(主機A)來說在遠程網絡——也就是在網絡B。
      主機A通過以上與目標主機B略顯複雜的“與運算”後,完成了路由判斷的第一步——判斷出了目標主機B在遠程網絡。接下來主機A需要“思考”的是如何才能夠到達主機B所在的網絡?主機A首先會查詢自己的路由表,看在自己的路由表中能否找到去往目標網絡(網絡B)的路由條目。爲了方便大家理解,我將主機A的路由表輸出顯示如下:


C:\>route print
Active Routes:
Network Destination         Netmask             Gateway          Interface         Metric
               0.0.0.0             0.0.0.0            192.168.0.1      192.168.0.5         10
             127.0.0.0          255.0.0.0            127.0.0.1         127.0.0.1           1
           192.168.0.0     255.255.255.0      192.168.0.5      192.168.0.5         10
           192.168.0.5   255.255.255.255       127.0.0.1         127.0.0.1           10
         192.168.0.255   255.255.255.255   192.168.0.5      192.168.0.5         10
             224.0.0.0           240.0.0.0         192.168.0.5      192.168.0.5         10
       255.255.255.255  255.255.255.255   192.168.0.5      192.168.0.5         1

Default Gateway: 192.168.0.1

      從主機A路由表的輸出顯示中我們沒有找到與目標主機B所在的網絡相匹配的具體路由,也就是說主機A沒有到達1.1.1.0這個網絡的路由。但是我們注意到在該路由表的最後一行輸出的是:  Default Gateway(默認/缺省網關): 192.168.0.1 路由表最後一行的輸出說明主機A在沒有找到能夠到達目標網絡的具體路由的情況下,會將發往目標網絡的數據包發送到默認/缺省網關(192.168.0.1),由這個默認/缺省網關再將該數據包轉發到目標網絡。
      好了,現在主機A知道了默認網關(192.168.0.1)是自己的下一跳地址,主機A開始執行封裝。封裝信息如下:


目的MAC:
下一跳設備的MAC
源MAC:
主機A的MAC地址
源IP:
192.168.0.5
目的IP:
1.1.1.5
ICMP報頭 (主機A)
Ping 1.1.1.5
     
      在以上所封裝的尋址信息當中,主機A唯一不知道的就是“下一跳設備的MAC地址”,這裏的“下一跳設備MAC地址”是指主機A的默認網關192.168.0.1的F0/0接口的MAC地址。這裏容易讓人產生一個困惑,主機A的目的IP地址是主機B,那麼爲什麼主機A封裝的鏈路層的目的MAC地址卻是路由器F0/0的MAC地址呢?原因是當初人們在設計數據鏈路層時主要考慮如何解決一條線路上相鄰兩端設備之間的通信。
      從這個網絡場景中我們看到主機A和主機B從各自所處的物理位置上看並不屬於相鄰的兩臺設備(中間隔着一臺路由器)。既然主機B並不是主機A直接相鄰的設備,那麼主機A在數據鏈路層封裝的目的MAC地址當然就不可能是主機B了。主機A通過IP路由的流程判斷和查詢路由表知道要想到達主機B就必須將數據包發給路由器A的F0/0接口(F0/0接口也是主機A到達主機B必經的直接相鄰的接口),因此F0/0的MAC地址就成爲主機A在數據鏈路層封裝的目的MAC地址。在本例中假如主機A要給Server A發送數據而不是給主機B,那麼主機A在數據鏈路層封裝的目的MAC地址就是Server A的MAC地址,因爲Server A與主機A是彼此直接相鄰的設備。那麼對於主機A來說它是否知道路由器F0/0接口的MAC地址呢?主機A是不知道的。所以接下來主機A需要做的是如何才能找到F0/0接口的MAC地址以完成數據鏈路層的封裝成幀。首先主機A查看自己的ARP緩存表,每臺主機/電腦都有這個ARP緩存表,該緩存表記錄着與自己發生過通信的所有的直接相鄰設備或主機的硬件地址(MAC地址),ARP緩存表經過一段時間會自動刪除,比如Windows 的動態 ARP 緩存條目不超過 10 分鐘就會被刪除。如果主機A與路由器之前曾發生過通信,主機A自然能在ARP緩存表中找到路由器F0/0的硬件MAC地址,可是如果這是主機A與路由器的第一次通信,則主機A會向網絡A上發送發送ARP廣播請求數據包,該ARP請求包包含的關鍵信息如下:


發送方IP地址(192.168.0.5) 發送方MAC地址(主機A MAC地址)
目的IP地址(192.168.0.1) 目的MAC地址(000000000000)

      以上ARP請求包中封裝的三項信息都是已知的,只有“目的MAC地址”這一信息是未知的(全“0”填充)。當該ARP請求包發送到網絡A上時,網絡A上的設備接收該ARP包並查看該ARP包內的具體封裝信息。因爲該ARP包中封裝的目的IP地址是192.168.0.1,所以只有具有192.168.0.1這個IP的接口或設備才應答該ARP查詢請求,應答者會將自己的硬件MAC地址封裝到這個ARP應答數據包中。這個ARP應答數據包(本例中由路由器F0/0接口發出ARP應答)封裝的關鍵信息如下:


發送方IP地址(192.168.0.1) 發送方MAC地址(F0/0接口MAC地址)
目的IP地址(192.168.0.5) 目的MAC地址(主機A的MAC地址)
   
      主機A通過ARP協議解析出路由器F0/0接口的MAC地址從而完成了數據鏈路層的封裝。通過主機A這個解析過程大家可以看到主機A在第一次與默認網關通信時的確是費了一番周折,爲了找到默認網關F0/0接口的MAC地址也“耽擱”了一些時間,這也是爲什麼我們在第一次ping網絡上某臺主機/設備的時候通常會看到第一個數據包會出現“request timed out!”(請求超時!)的情況。最後主機A完成MAC地址解析後將該幀發送到網絡A上,該幀的具體封裝如下:


目的MAC:
路由器F0/0接口
源MAC:
主機A的MAC地址
源IP:
192.168.0.5
目的IP:
1.1.1.5
ICMP報頭 (主機A) Ping 1.1.1.5

      因爲該幀的目的MAC地址是F0/0的MAC地址,所以只有路由器的F0/0接口接收並處理該數據幀。路由器將該幀解封裝並查看網絡層的封裝信息,路由器看到該數據包網絡層封裝的目的地址是1.1.1.5。路由器爲了將這個數據包轉發到1.1.1.5,使用前面提到的“與運算”的方法進行計算,依據計算結果判斷目標地址1.1.1.5對於路由器自己來說在本地網絡還是在遠程網絡。路由器所做“與運算”過程簡述如下:

      路由器的F0/0接口上的IP地址192.168.0.1與F0/0接口的子網掩碼255.255.255.0作“與運算”得到“結果1”;目標地址1.1.1.5與路由器F0/0接口的子網掩碼255.255.255.0作“與運算”得到“結果2”;“結果1”與“結果2”並不相同,證明目標地址1.1.1.5並不處在路由器的F0/0接口所在的網絡A。
      路由器的另一個接口F0/1的IP地址1.1.1.1與F0/1接口的子網掩碼255.255.255.0作“與運算”得到“結果3”;目標地址1.1.1.5與F0/1接口上
的子網掩碼255.255.255.0作“與運算”得到“結果4”;“結果3”與“結果4”相同,證明目標地址1.1.1.5處在路由器的F0/1接口所在的網絡B。這也就意味着路由器B只需將發送給1.1.1.5的數據包從F0/1接口發出去就OK了。我們將路由器的這種路由稱爲直接路由。

      路由器得出上述結論後立刻執行封裝,封裝的具體信息如下:

目的MAC:
主機B的MAC地址
源MAC:
路由器F0/1接口
源IP地址
192.168.0.5
目的IP地址
1.1.1.5
ICMP報頭 (主機A) Ping 1.1.1.5

      在以上路由器封裝的具體信息中的目的MAC地址是主機B的MAC地址。如果路由器在ARP緩存表中並未查到主機B的硬件MAC地址,則路由器仍然會像主機A查詢路由器F0/0接口硬件MAC地址一樣發送ARP請求來查詢主機B的MAC地址。關於路由器對主機B 硬件MAC地址的查詢過程在這裏就不再重複了。
      這樣主機B就收到了該數據幀,主機B對該幀進行解封裝看到了網絡層封裝的目的IP地址,知道這個數據包的目的地是自己後,主機B繼續對其拆封裝並查看ICMP報頭內的信息得出結論:這是一個請求自己進行反饋的數據包,需要自己將這條“數據包已到達主機B”的信息回饋給主機A。因此主機B爲了將回饋信息順利送達主機A需要經過如封裝:

目的MAC:
路由器F0/1接口
源MAC:
主機B的MAC地址
源IP:
1.1.1.5
目的IP:
192.168.0.5
ICMP報頭 對(主機A) Ping 1.1.1.5的應答

      主機B在發送應答數據包時封裝的目的MAC地址是路由器F0/1接口的MAC地址,這也是主機B通過路由判斷和與運算得出的結論,對於主機B來說路由器F0/1接口是它的下一跳。
      路由器F0/1接口在收到主機B發來的數據包後爲了將其轉發給主機A再次進行封裝,具體的封裝信息如下:

目的MAC:
主機A的MAC地址
源MAC:
路由器F0/0接口
源IP:
1.1.1.5
目的IP:
192.168.0.5
ICMP報頭 對(主機A) Ping 1.1.1.5的應答

      從主機A到路由器再到主機B執行的封裝過程中我們可以看出網絡層封裝的信息是始終不變的:源IP是192.168.0.5 目的IP是1.1.1.5。始終變化的是一跳一跳的硬件MAC地址。從主機B到路由器再到主機A執行的封裝過程中我們同樣可以看出網絡層封裝的信息也是始終不變的:源IP是1.1.1.5目的IP是192.168.0.5。始終變化的還是一跳一跳的硬件MAC地址。
      以上我們在IP路由封裝的過程中得到的這一結論並不適用於另外一個網絡技術——NAT(網絡地址轉換)。關於NAT我們將在其他的文章中繼續討論。
發佈了33 篇原創文章 · 獲贊 126 · 訪問量 29萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章