Note: this series starts from Ethernet packet sniffing.
參考 RFC791:
Linux 核心則定義在 include/uapi/linux/ip.h
中:
saddr
與 daddr
–- 發送者與接收者的 IPsaddr
為發送方的 IPv4 位址,而 daddr
則為接送方的 IPv4 位址。
id
與 frag_off
–- 屬於哪一份資料的哪一個部分?使用 IP 協定傳輸資料時,一個完整的資料有可能被切分成多個部分,稱為 fragment。除此之外,當路由器在轉送封包時,因為不同傳遞媒介的 MTU (maxima transmision unit) 有可能不同。如果從一個網路轉送給另外一個網路時,發現單一封包擠不進另外一個網路的 MTU 時,就有可能在轉送的過程中切割從這些封包。比如說:乙太網路單一訊框能承載的資料大小與 WiFi 不同,因此若路由器要將來自 WiFi 的封包轉送給乙太網路,就可能需要切割封包。這些切割的小片段稱為 fragement。
這些切割的片段最終需要組合起來,而組合的依據就是 id
與 frag_offset
。 id
來確認這些封包的內容是否同屬於一個完整的資料,而 frag_offset
則表示這個封包裝得是原先封包哪一個部分的資料。他的單位並不是位元組,而是以 8 位元組為一個單位。也就是當 frag_offset
為 時,指得是「這個封包裝的 data
,裝的是原先封包的資料中第 位元組開始」的資料。
protocol
–- 上層協定是什麼?protocol
欄位用來表示這一個 IP 封包是拿來裝「L4 中哪個協定」的資料(按:目前所在的 IP 協定是 L3)。
ttl
–- 還可以被轉送幾次?雖然英文用語是 time to live,但實際上是一個用來表示「這個封包還可以被路由器轉送幾次」的計數器。這個欄位一開始會是個非零的數值,而每當封包被路由器轉送一次,這個數值就會減一。當一個路由器發現一個封包的 ttl
欄位歸零時,就會捨棄這個封包。
會有這個理由是:如果大量迷路的封包累積在網路中不斷地被轉送,會佔據大量的流量。為了不讓他們持續遺留在網路中於是設計這個機制。
flag
–- 封包的屬性DF
–- 封包能不能被切割?指定封包的屬性。比如說 DF
欄位表示這個封包可不可以被切割?如果 flag
中被設定了這個值,就表示這個封包不可以被切割。那麼要嘛就幫他找一條都不用分割的路徑,或是如果這樣的路徑找不到,就只能丟棄它。
MF
–- 是不是某個封包的片段?而 MF
位元表示「這個封包是某個被切割的封包的其中一個片段」。如果設為 1
,表示「目前這個封包不是最後一個片段」; 反之就表示「它是最後一個片段」:
tos
–- 封包的種類這 8 個位元又細分為幾個欄位。包含:
這個欄位的前 3 個位元表示這個封包是一般資料的封包?或是網路的控制封包?
相關常數在 include/uapi/linux/ip.h
中有定義:
D
、T
、R
D
設為 1
表示 low delay,而 T
設為 1
表示 high throughput、R
被設為 1
則表示 high reliability:
在 include/uapi/linux/ip.h
中有定義相關常數:
這些欄位用來表示一個封包處理的優先程度。
tot_len
–- 封包的長度封包的總長度。
check
–- 校驗碼這整個 header 的 checksum(包含 option)
version
–- IP 協定的版本這個封包使用 IPv4 或是 IPv6。