/usr/src/linux/include/linux/ip.h
struct iphdr {
#if defined(__LITTLE_ENDIAN_BITFIELD)
__u8 ihl:4,
version:4;
#elif defined (__BIG_ENDIAN_BITFIELD)
__u8 version:4,
ihl:4;
#else
#error "Please fix <asm/byteorder.h>"
#endif
__u8 tos;
__be16 -tot_len;
__be16 -id;
__be16 -frag_off;
__u8 ttl;
__u8 protocol;
__be16 -check;
__be32 -saddr;
__be32 -daddr;
};
31 0
|----|----|------|--|-------------------|----------
|ver |ihl | -tos | -| tot_len |
|----|----|------|--|-------------------|
| id | frag_off -|
|---------|---------|-------------------|
| ttl |protocol | check | 20 Bytes
|---------|---------|-------------------|
| saddr |
|---------------------------------------|
| daddr |
|---------------------------------------|----------
| |
-| options | 40 Bytes
| |
|---------------------------------------|
IPv4 (Internel協(xié)議)頭部
iphdr->version
版本(4位),目前的協(xié)議版本號是4,因此IP有時也稱作IPv4。
iphdr->ihl
首部長度(4位):首部長度指的是IP層頭部占32 bit字的數(shù)目(也就是IP層頭部包含多少個4字節(jié) -- 32位),包括任何選項。由于它是一個4比特字段,因此首部最長為60個字節(jié)。普通IP數(shù)據(jù)報(沒有任何選擇項)字段的值是5 <==> 5 * 32 / 8 = 5 * 4 = 20 Bytes
iphdr->tos
服務(wù)類型字段(8位): 服務(wù)類型(TOS)字段包括一個3 bit的優(yōu)先權(quán)子字段(現(xiàn)在已被忽略),4 bit的TOS子字段和1 bit未用位但必須置0。4 bit的TOS子字段分別代表:最小時延、最大吞吐量、最高可靠性和最
小費(fèi)用。4 bit中只能設(shè)置其中1 bit。如果所有4 bit均為0,那么就意味著是一般服務(wù)。
iphdr->tot_len
總長度字段(16位)是指整個IP數(shù)據(jù)報的長度,以字節(jié)為單位。利用首部長度字段和總長度字段,就可以知道 IP數(shù)據(jù)報中數(shù)據(jù)內(nèi)容的起始位置和長度。由于該字段長16比特,所以IP數(shù)據(jù)報最長可達(dá)65535字節(jié)
總長度字段是IP首部中必要的內(nèi)容,因為一些數(shù)據(jù)鏈路(如以太網(wǎng))需要填充一些數(shù)據(jù)以達(dá)到最小長度。盡管以太網(wǎng)的最小幀長為46字節(jié),但是IP數(shù)據(jù)可能會更短。如果沒有總長度字段,那么IP層就不知道46字節(jié)中有多少是IP數(shù)據(jù)報的內(nèi)容。
iphdr->id
標(biāo)識字段(16位)唯一地標(biāo)識主機(jī)發(fā)送的每一份數(shù)據(jù)報。通常每發(fā)送一份報文它的值就會加1。
iphdr->frag_off (16位)
frag_off域的低13位 -- 分段偏移(Fragment offset)域指明了該分段在當(dāng)前數(shù)據(jù)報中的什么位置上。除了一個數(shù)據(jù)報的最后一個分段以外,其他所有的分段(分片)必須是8字節(jié)的倍數(shù)。這是8字節(jié)是基本分段單位。由于該域有13個位,所以,每個數(shù)據(jù)報最多有8192個分段。因此,最大的數(shù)據(jù)報長度為65,536字節(jié),比iphdr->tot_len域還要大1。
iphdr->frag_off的高3位
(1) 比特0是保留的,必須為0;
(2) 比特1是“更多分片”(MF -- More Fragment)標(biāo)志。除了最后一片外,其他每個組成數(shù)據(jù)報的片都要把該比特置1。
(3) 比特2是“不分片”(DF -- Don't Fragment)標(biāo)志,如果將這一比特置1,IP將不對數(shù)據(jù)報進(jìn)行分片,這時如果有需要進(jìn)行分片的數(shù)據(jù)報到來,會丟棄此數(shù)據(jù)報并發(fā)送一個ICMP差錯報文給起始端。
|---|-------------|
|DM0| offset |
|---|-------------|
15 1312 0
iphdr->ttl
TTL(time-to-live) -- 8位,生存時間字段設(shè)置了數(shù)據(jù)報可以經(jīng)過的最多路由器數(shù)。它指定了數(shù)據(jù)報的生存時間。TTL的初始值由源主機(jī)設(shè)置(通常為32或64),一旦經(jīng)過一個處理它的路由器,它的值就減去1。當(dāng)該字段的值為0時,數(shù)據(jù)報就被丟棄,并發(fā)送ICMP報文通知源主機(jī)。
TTL(Time to live)域是一個用于限制分組生存期的計數(shù)器。這里的計數(shù)時間單位為秒,因此最大的生存期為255秒。在每一跳上該計數(shù)器必須被遞減,而且,當(dāng)數(shù)據(jù)報在一臺路由器上排隊時間較長時,該計數(shù)器必須被多倍遞減。在實踐中,它只是跳計數(shù)器,當(dāng)它遞減到0的時候,分組被丟棄,路由器給源主機(jī)發(fā)送一個警告分組。此項特性可以避免數(shù)據(jù)報長時間地逗留在網(wǎng)絡(luò)中,有時候當(dāng)路由表被破壞之后,這種事情是有可能發(fā)生的。
iphdr->protocol
協(xié)議字段(8位): 根據(jù)它可以識別是哪個協(xié)議向IP傳送數(shù)據(jù)。
當(dāng)網(wǎng)絡(luò)層組裝完成一個完整的數(shù)據(jù)報之后,它需要知道該如何對它進(jìn)行處理。協(xié)議(Protocol)域指明了該將它交給哪個傳輸進(jìn)程。TCP是一種可能,但是UDP或者其他的協(xié)議也是可能的。
iphdr->check
首部檢驗和字段(16位)是根據(jù)IP首部計算的檢驗和碼。它不對首部后面的數(shù)據(jù)進(jìn)行計算。 ICMP、IGMP、UDP和TCP在它們各自的首部中均含有同時覆蓋首部和數(shù)據(jù)檢驗和碼。
為了計算一份數(shù)據(jù)報的IP檢驗和,首先把檢驗和字段置為0。然后,對首部中每個16 bit進(jìn)行二進(jìn)制反碼求和(整個首部看成是由一串16 bit的字組成),結(jié)果存在檢驗和字段中。當(dāng)收到一份IP數(shù)據(jù)報后,同樣對首部中每個16 bit進(jìn)行二進(jìn)制反碼的求和。由于接收方在計算過程中包含了發(fā)送方存在首部中的檢驗和,因此,如果首部在傳輸過程中沒有發(fā)生任何差錯,那么接收方計算的結(jié)果應(yīng)該為全1。如果結(jié)果不是全1(即檢驗和錯誤),那么IP就丟棄收到的數(shù)據(jù)報。但是不生成差錯報文,由上層去發(fā)現(xiàn)丟失的數(shù)據(jù)報并進(jìn)行重傳。
iphdr->saddr
32位源IP地址
iphdr->daddr
32位目的IP地址
網(wǎng)絡(luò)字節(jié)序
4個字節(jié)的32 bit值以下面的次序傳輸:首先是0~7bit,其次8~15bit,然后16~23bit,最后是24~31 bit。這種傳輸次序稱作big endian字節(jié)序。由于TCP/IP首部中所有的二進(jìn)制整數(shù)在網(wǎng)絡(luò)中傳輸時都要求以這種次序,因此它又稱作網(wǎng)絡(luò)字節(jié)序。
posted on 2008-11-21 10:47
水 閱讀(1448)
評論(0) 編輯 收藏 引用 所屬分類:
tcp/ip