2007年6月19日 星期二

[TCP/IP Illustrated] IP(Internet Protocol)

簡介

IP(Internet Protocol) 可說是 TCP/IP 中眾多協定中最重要的一個也不為過,因為有許多協定(TCP、UDP、ICMP、IGMP....等等)都必須要靠 IP 將資料封裝成 IP datagram 來傳送;不過 IP 是屬於不可靠的傳輸協定,因為它僅提供了簡單的錯誤處理功能,作用僅是當發現錯誤後,就回傳 ICMP 訊息給傳送方。因此,若需要更複雜的錯誤處理功能,就必須要在 IP 上層的其他協定去實作。

然而,IP 還被稱為是 connectionless 的協定,原因是因為在傳輸的過程中,IP 並不會為傳輸的資料維護 state 資訊,所以就是....一直送、一直送.....等到發現錯誤再重送....所以也有可能原先傳遞出去的 IP datagram,分別走了不同的路徑,而讓目的地接收資料的順序不一樣。

不過也因為 IP 沒有其他很複雜的功能在其中,因此在使用上效率也是最好的。

在這一篇文章中,會介紹 IP Header 的組成、IP Routing、Subnetting....等等,以下就來慢慢說明。


IP Header

之前一直提的 IP datagram 就是在從上層協定傳給 IP 的資料,再加上 IP header 所形成的,一般來說,IP header 的大小為 20 bytes,以下用一張圖來說明 IP header 中的各欄位:

上圖為一個完整的 IP datagram,其中以紅色框線框起來的部分(也有可能包含到紅框下方的 options),即為 IP header;而比較需要留意的是,資料以 1 bytes(8 bits) 為單位進行傳送,由圖中的左邊編號為 0 所屬的 byte 開始傳送,傳送的順序分別是:
  1. 第 0~7 bits
  2. 第 8~15 bits
  3. 第 16~23 bits
  4. 第 24~31 bits
  5. 以下以此類推..............
這種傳送順序,稱為 Network Byte Order(NBO),TCP/IP 所使用的傳送順序即是如此。

但不巧的,NBO 與某些作業系統或是機器上的 Host Byte Order(HBO) 卻有些是相反的! 因此在撰寫網路程式的時候,程式設計師就必須去判斷 NBO 與 HBO 的順序是否相同,來決定是否進行轉換。
【註】若有興趣深入瞭解可以參考此篇文章(Beej的網路socket編程指南)

接著要來介紹各個欄位:
  • version (4 bits)
    表示協定的版本,一般來說是 4,表示 IPv4;但目前 IPv6 已經開始慢慢有在使用了
  • length (4 bits)
    指定 header 長度為 4 bytes(32 bits) * length。架設情況如下:
    length=5:header 長度為 4 bytes * 5 = 20 bytes (此為預設值,沒有 options 的情況下)
    length=6:header 長度為 4 bytes * 6 = 24 bytes (即表示 options 欄位的長度為 4 bytes)
    因此可以瞭解,header length 最多可以指定到 4 bytes * 15(1111) = 60 bytes。
  • type of serviceTOS (8 bits)
    雖然此欄位長度為 8 bits,但前三個與最後一個 bit 都不用理會,因為在目前都沒在使用,有在使用的為第 4~7 的 bit,以粗體紅字表示 => 00000000
    此 4 個 bit 分別要表達的是:
    4th:minimize delay
    5th:maximize throughput
    6th:maximize reliability
    7th:minimize monetary cost
    每個 bit 所訴求的目的並不一樣,因此 TOS 的設定就是根據協定的特性需求來決定 TOS 所應該設定的值,以下有一張簡單的表作為範例:

    從上表各種協定與 TOS 的搭配,應該不難看出每個協定所著重的重點為何吧!
  • total length (16 bits)
    指定整個 IP datagram 的大小,單位為 byte,由於有 16 bits 可以表示,因此每個 IP datagram 最大可以到 65535 bytes。這正好可以驗證上一篇所提到的,MTU 最大不會超過 65535 bytes。但是一般說來,過大的 IP datagram 由於傳送上的困難或是其他協定的限制,會被切割為好幾個小部分。
    【註】透過 total length 與 length 欄位的搭配,就可以計算出在 IP datagram 中資料的實際大小
  • identification (16 bits)
    此欄位是用來識別傳送端所發出的 IP datagram 之用,每個 IP datagram 都會有一個 unique 的 identification 值,一般來講就是以遞增值的方式來作為識別之用
  • flags (3 bits) & fragment offset (13 bits)
    此兩欄位是作為進行 fragmentation 時之用
  • time to liveTTL (8 bits)
    這個欄位中所儲存的值,代表送出的 IP datagram 可以通過 router 數量的上限,此值由傳送端設定,每經過一個 router 會減少 1,當值減為 0 後,則會被丟棄不再繼續傳送,然後傳送端會收到 ICMP 訊息作為通知,避免傳送端一直送出無法達到目的地的封包。
  • protocol (8 bits)
    此欄位在第一篇學習筆記中就提過啦! 目的是在記錄使用 IP 傳送資料的是上層的哪一個協定
  • header checksum (16 bits)
    作為檢查 IP header 之用,跟其他協定(例如:TCP、UDP、ICMP....etc)的 header 無關,因為其他協定的 header 有自己的 checksum 欄位。
    另外,由於 checksum 是依據 IP header 中各欄位所計算出來的,因此在 IP datagram 經過 router 而 TTL 減 1 後,router 會重新計算 checksum 的值並繼續傳遞 IP datagram
  • source IP address (32 bits)
  • destination IP address (32 bits)
  • options (不定長度)
    最後這個欄位就比較少用到了,長度不固定,但以 4 bytes(32 bits) 為單位,而有可能被用在以下幾個地方:
    • 加強安全性
    • 記錄 route 資訊的
    • 記錄時間戳記
    • 指定 routing 的路徑


IP Routing

要知道資料是如何在廣大的網際網路上傳遞? 如何從傳送端,跨過一個個 router 到達目的地? 就是 IP Routing 的觀念了!

當傳送端要傳送 datagram 時,而接收端卻不在同一個網段內,此時 datagram 就會被送到預設的 router 上,router 在根據本身的 routing table 與 datagram 中的目的地比對後,決定要傳送的下一個 router,一直到 datagram 到達目的地為止。

在 IP Layer 中,不僅可以扮演 host 的角色,也可以扮演成 router 的角色,也就是說,不但可以接收資料,也可以傳遞資料(其實 host 與 router 的差別就在於是否有 forward 資料)。而在目前的作業系統(Unix、Linux....etc)都支援這樣子的功能,只要經過正確的設定,以及安裝多張的網路卡,就可以讓電腦不僅僅只能接收資料,還能提供 router 的功能。

而 IP Layer 是怎樣處理從 interface 接收到的 datagram 呢? 以下是其處理規則:
  1. 檢查 datagram 中的 destination IP address 是否屬於自己的 IP address 或是 IP broadcast address
  2. 是(Yes)
    此 datagram 會根據其 IP header 中指定的 protocol,被 IP Layer 往上層送由正確的協定來處理
  3. 否(No)
    • 若此 IP Layer 有被設定為具有 router 的功能,則會將此 datagram 由規則中指定的 interface forward 出去
    • 若 IP Layer 中無提供 route 的功能,則此 datagram 會被丟棄,並且不對傳送方進行任何通知

不論是用一般的主機作為 router,或是直接使用單純的 router,最重要的是「routing table」;routing table 是一條條規則所組成,用來描述到不同目的地的 datagram,應該經由那個 interface 將其 forward 出去,也就是應該要走哪條路徑,一般來說,每條在 routing table 中的規則都會包含以下幾種資訊:
  1. Destination IP address
    這邊指的有兩種可能,分別是:
    • host address
      單一 host 的 IP address,例如:140.137.10.200
    • network address
      某個網段,例如:140.137.12.0/24
  2. Next-Hop router
    這部分的資訊是儲存在名稱為「Next-Hop router」的欄位上,同樣有兩種可能,分別是:
    • Next-Hop router
      要到上述目的地 IP 位址的下一個必須傳送的 router
    • 直接連接到 router 的網段中的 IP address
  3. Flags
    在 Flags 的部分是由兩個 flag 所組成。
    第一個 flag 描述 Destination IP address 為 host address 或是 network address。
    第二個 flag 則描述 next-hop router 欄位中所儲存的,是下一個要將 datagram 繼續 forward 到目的地的 router,或是直接連接到此 router 的網段
  4. 指定從哪些 interface 經過的 datagram 可以將其 forward

IP routing 是以 hop-by-hop 為基礎(這裡指的 hop 即為 router)所進行的,從 routing table 可以看出,並沒有涵蓋相當多的 routing 資訊,因此 IP 是無法知道 datagram 傳送到任何目的地的完整傳送路徑,但是 routing table 中都會有足夠的訊息至少可以讓 datagram 傳送到下一個距離目的地更近的 router,其作法如下:
  1. 根據 datagram 中的 destination IP address 欄位,在 routing table 中搜尋是否有符合的規則;若有發現合適規則,就根據規則將 datagram 傳送到下一個 hop 或是到另一個直接連接的 interface
  2. 若第一個步驟中沒有合適的規則,就會再次尋找,但是僅會尋找是否有符合的 network ID(網段);若有發現合適規則,就根據規則將 datagram 傳送到下一個 hop 或是到另一個直接連接的 interface
  3. 若前兩個步驟都沒發現合適規則,那就會使用 default 的規則將 datagram 傳送到下一個 hop
如果以上三個步驟都無法完成,則表示該 datagram 是無法傳送出去的,而傳送端就會收到 "host unreachable" 的錯誤訊息。

或許有人會問,為什麼不在 routing table 把所有規則都涵蓋起來就好了呢? 恩.....我想應該沒有人希望 routing table 中可能包含了數萬條的規則吧.....


子網路

這個部分包含了 Subnet Addressing 以及 Subnet Mask,慢慢解釋實在太久,剛好在網路上有找到講解得很詳細的文章,以下是連結:

IP 位址

2 則留言: