天天看點

網際協定IP無連接配接、不可靠的協定 資料報 分片和重組IP位址

無連接配接、不可靠的協定

IP是網絡層協定,它總是盡最大的努力将分組傳輸到目的終點。為了達到最大努力,IP放棄了差錯檢驗和跟蹤,分組在傳輸過程中可能會出現丢包或者損壞(一般在高層提供解決方案),故IP是“不可靠的”;IP将每個分組作為一個獨立的封包發送出去,在分組交換網絡中從同一起點出發的這些分組可能會通過不同的路由傳輸到達終點(路徑的不同導緻到達終點時候的分組也會出現亂序問題),是以IP是“無連接配接的”。

注:

或許會有疑問說IP報頭不也提供了“檢驗和”來進行差錯檢驗功能嗎?怎麼說“IP放棄了差錯檢驗”?

其實,前面說的“IP放棄了差錯檢驗”是針對整個資料包來說的。要知道,IP分組的檢驗和隻是作用在資料報首部,而對封包的資料部分并不做差錯檢驗。以上做法是有更深層次的目的的:IP封包在網絡中是通過路由節點逐跳傳輸的,每次經過一個路由裝置就會修改封包的IP頭部而資料部分保持不變,因為IP頭部修改頻繁故對該部分提供差錯檢驗,使得收到該封包的接收端可以判斷是否接收(通過計算檢驗和是否正确)。若是IP檢驗和将封包的資料封包一起包含起來,則在每個路由節點都會對基本不變的資料部分進行一次處理,這将增加路由的時間開銷,違背了IP“盡最大努力”的原則。是以對于分組封包資料部分的檢驗一般都是由IP之上的高層協定來提供。     不得不贊歎:)

資料報

在IP層的分組叫做資料報。

資料報的格式

網際協定IP無連接配接、不可靠的協定 資料報 分片和重組IP位址

其中:

1、版本:有版本4和版本6

2、首部長度:定義資料報的總長度,以4位元組為機關計算。首部長度在 20~60位元組之間。

3、服務類型:前三位為優先位,後面兩位為TOS位,最後一位沒有使用。

4、總長度:定義以位元組計的資料報總長度(首部加上資料),故資料報長度限制為65535

5、辨別:标志從源主機發出的資料報。該字段和Flags和Fragment Offest字段聯合使用,對較大的上層資料包進行分段(fragment)操作。路由器    将一個包拆分後,所有拆分開的小包被标記相同的值,以便目的端裝置能夠區分哪個包屬于被拆分開的包的一部分。

6、标志:該字段第一位不使用。第二位是DF(Don't Fragment)位,DF位設為1時表明路由器不能對該上層資料包分段。如果一個上層資料包無法在    不分段的情況下進行轉發,則路由器會丢棄該上層資料包并傳回一個錯誤資訊。第三位是MF(More Fragments)位,當路由器對一個上層數    據包分段,則路由器會在除了最後一個分段的IP包的標頭中将MF位設為1。

8、分片偏移:表示這個分片在整個資料報中的相對位置,偏移值以8位元組為度量機關

9、生存時間:當IP包進行傳送時,先會對該字段賦予某個特定的值。當IP包經過每一個沿途的路由器的時候,每個沿途的路由器會将IP包的TTL值減少1。如果TTL減少為0,則該IP包會被丢棄。

10、協定:定義使用IP層服務的高層協定。

11、檢驗和:用來做IP頭部的正确性檢測,但不包含資料部分。 因為每個路由器要改變TTL的值,是以路由器會為每個通過的資料包重新計算這個值

12、源位址:定義源點的IP位址    

13:目的位址:定義終點的IP位址

14、選項:這是可變部分,對資料報來說不是必須的,主要用于網絡的測試和排錯。

定義IP分組頭格式

 linux 中對于 IP頭部 的定義

include/linux/ip.h

/*區分服務:TOS位*/
#define IPTOS_TOS_MASK          0x1E                     
#define IPTOS_TOS(tos)          ((tos)&IPTOS_TOS_MASK)      
#define IPTOS_LOWDELAY          0x10  //最小延時
#define IPTOS_THROUGHPUT        0x08  //最大吞吐量
#define IPTOS_RELIABILITY       0x04  //最高可靠性
#define IPTOS_MINCOST           0x02  //最小代價

/*區分服務:優先位*/
#define IPTOS_PREC_MASK         0xE0
#define IPTOS_PREC(tos)         ((tos)&IPTOS_PREC_MASK)
#define IPTOS_PREC_NETCONTROL           0xe0
#define IPTOS_PREC_INTERNETCONTROL      0xc0
#define IPTOS_PREC_CRITIC_ECP           0xa0
#define IPTOS_PREC_FLASHOVERRIDE        0x80
#define IPTOS_PREC_FLASH                0x60
#define IPTOS_PREC_IMMEDIATE            0x40
#define IPTOS_PREC_PRIORITY             0x20
#define IPTOS_PREC_ROUTINE              0x00

/* IP options */
#define IPOPT_COPY              0x80  //複制
#define IPOPT_CLASS_MASK        0x60  //類
#define IPOPT_NUMBER_MASK       0x1f  //數

#define IPOPT_COPIED(o)         ((o)&IPOPT_COPY)
#define IPOPT_CLASS(o)          ((o)&IPOPT_CLASS_MASK)
#define IPOPT_NUMBER(o)         ((o)&IPOPT_NUMBER_MASK)

/*類*/
#define IPOPT_CONTROL           0x00  //資料報控制  
#define IPOPT_RESERVED1         0x20  //保留
#define IPOPT_MEASUREMENT       0x40  //排錯和管理
#define IPOPT_RESERVED2         0x60  //保留

/*數*/
#define IPOPT_END       (0 |IPOPT_CONTROL)             //選項結束
#define IPOPT_NOOP      (1 |IPOPT_CONTROL)             //無操作
#define IPOPT_SEC       (2 |IPOPT_CONTROL|IPOPT_COPY)  
#define IPOPT_LSRR      (3 |IPOPT_CONTROL|IPOPT_COPY)  //不嚴格的源路由
#define IPOPT_TIMESTAMP (4 |IPOPT_MEASUREMENT)         //時間戳
#define IPOPT_CIPSO     (6 |IPOPT_CONTROL|IPOPT_COPY)
#define IPOPT_RR        (7 |IPOPT_CONTROL)             //記錄路由
#define IPOPT_SID       (8 |IPOPT_CONTROL|IPOPT_COPY)
#define IPOPT_SSRR      (9 |IPOPT_CONTROL|IPOPT_COPY)  //嚴格的源路由
#define IPOPT_RA        (20|IPOPT_CONTROL|IPOPT_COPY)

#define IPVERSION       4
#define MAXTTL          255
#define IPDEFTTL        64

#define IPOPT_OPTVAL 0
#define IPOPT_OLEN   1
#define IPOPT_OFFSET 2
#define IPOPT_MINOFF 4
#define MAX_IPOPTLEN 40
#define IPOPT_NOP IPOPT_NOOP
#define IPOPT_EOL IPOPT_END
#define IPOPT_TS  IPOPT_TIMESTAMP

#define IPOPT_TS_TSONLY         0               /* timestamps only */
#define IPOPT_TS_TSANDADDR      1               /* timestamps and addresses     */
#define IPOPT_TS_PRESPEC        3               /* specified modules only */

#define IPV4_BEET_PHMAXLEN 8

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;
        __sum16 check;
        __be32  saddr;
        __be32  daddr;
        /*The options start here. */
};

           

選項

選項部分可以用于網絡的測試和排錯,但是對于每個資料報來說并不是必需的。簡單介紹一下幾個選項類型的作用:

無操作:用于選項之間的填充符。

選項結束:用于選項字段結束時的填充。

記錄路由:記錄分組網絡中處理資料報的路由器,最多可記錄9個路由器的IP。(ping程式中的 -R 選項)

嚴格的源路由:用于确定資料報在分組網絡中的傳輸路徑,不得經過未确定的路由器。(traceroute中的 -G 選項)

不嚴格的源路由:用于确定資料報在分組網絡中的傳輸路徑,可經過未确定的路由器。(traceroute中的 -g 選項)

時間戳:用于記錄路由器處理資料報的時間。

分片和重組

實體網絡有一個最大資料幀的限制,用MTU最大傳輸單元來表示,這是由網絡使用的硬體特性所決定的。在分組交換網中,資料報可能會經過多個不同的網絡,資料幀的傳輸必須适應各個網絡的MTU限制,是以資料報在到達終點之前需要經過多次的分片。

分片是在源主機或者網絡中經過的路由器上進行。資料分片後,每個分片都是新的獨立的資料報,并擁有有自己的首部。

分片後的資料可通過不同的路徑到達終點,最後在終點的目的主機上進行重組。

在IP封包首部,與分片重組有關的三個字段分别為:辨別、标志和分片偏移。辨別用于表示這些分片屬于同一原始資料報,目的主機通過辨別可以将分片重組成為一個資料報。标志用于分片控制和表示分片結束,字段第二位是不分片位,第三位是還有分片位。分片偏移用于确定該分片在整個原始資料報中的相對位置,以8位元組為度量機關。

IP位址

分類編址

分類編制将位址空間分成了5類:

每一類的位址

類别 A B C D E
二進制記法的差別(第一位元組) 10 110 1110 1111
點分十進制的差別(第一位元組) 0~127 128~191 192~223 224~239 240~255
位址數 2^31 2^30 2^29 2^28 2^28

其中,A、B、C類的IP位址分為網絡辨別和主機辨別兩個部分。網絡辨別用于辨別該IP屬于哪個機構的網絡,主機辨別用于辨別該機構網絡内唯一一台主機。D類和E類不進行劃分,D類位址用來進行廣播,E類位址是保留的。

類别 A B C
網絡辨別長度 一位元組 兩位元組 三位元組
主機辨別長度 三位元組 兩位元組 一位元組
預設掩碼 255.0.0.0 255.255.00.0 255.255.255.0

無分類編址

由于分類編址的設計,位址空間存在這些問題:A類中大型機構用不上那麼多的位址數(2^24)、B類中中等規模的機構也用不上(2^16),然而C類小型機構确會出現位址數(2^8)不夠用的情況。于是出現了另一種分類方式:無分類編址。無分類編址能夠靈活有效地根據位址數需求來劃分位址空間。

無分類編址存在着三個限制條件:位址數必須是2的乘方;掩碼必須定義在位址中以界定這個位址塊;位址塊中的第一個位址必須能夠被位址數整除。

繼續閱讀