TCP/IP協議棧中各層包頭的分析


IP協議是TCP/IP協議族中最爲核心的協議。它提供不可靠、無連接的服務,也即依賴其他層的協議進行差錯控制。在局域網環境,IP協議往往被封裝在以太網幀中傳送。而所有的TCP、UDP、ICMP、IGMP數據都被封裝在IP數據報中傳送。

TCP/IP報文封裝:

這裏寫圖片描述

一、MAC幀頭定義

typedef struct _MAC_FRAME_HEADER 
{ 
char m_cDstMacAddress[6]; //目的mac地址 
char m_cSrcMacAddress[6]; //源mac地址 
short m_cType;      //上一層協議類型,如0x0800代表上一層是IP協議,0x0806爲arp 
}attribute((packed))MAC_FRAME_HEADER,*PMAC_FRAME_HEADER;


二、IP頭結構的定義

typedef struct _IP_HEADER 
{ 
char m_cVersionAndHeaderLen;   //版本信息(前4位),頭長度(後4位) 
char m_cTypeOfService;       // 服務類型8位 
short m_sTotalLenOfPacket;     //數據包長度 
short m_sPacketID;         //數據包標識 
short m_sSliceinfo;         //分片使用 
char m_cTTL;           //存活時間 
char m_cTypeOfProtocol;       //協議類型 
short m_sCheckSum;        //校驗和 
unsigned int m_uiSourIp;      //源ip 
unsigned int m_uiDestIp;      //目的ip 
} attribute((packed))IP_HEADER, *PIP_HEADER ; 

三、tcp頭結構定義

typedef struct _TCP_HEADER 
{ 
short m_sSourPort;       // 源端口號16bit 
short m_sDestPort;        // 目的端口號16bit 
unsigned int m_uiSequNum;   // 序列號32bit 
unsigned int m_uiAcknowledgeNum; // 確認號32bit 
short m_sHeaderLenAndFlag;   // 前4位:TCP頭長度;中6位:保留;後6位:標誌位 
short m_sWindowSize;      // 窗口大小16bit 
short m_sCheckSum;       // 檢驗和16bit 
short m_surgentPointer;      // 緊急數據偏移量16bit 
}attribute((packed))TCP_HEADER, *PTCP_HEADER;

typedef struct _TCP_OPTIONS 
{ 
char m_ckind; 
char m_cLength; 
char m_cContext[32]; 
}attribute((packed))TCP_OPTIONS, *PTCP_OPTIONS;

四、UDP頭結構的定義

typedef struct _UDP_HEADER 
{ 
unsigned short m_usSourPort;    // 源端口號16bit 
unsigned short m_usDestPort;    // 目的端口號16bit 
unsigned short m_usLength;     // 數據包長度16bit 
unsigned short m_usCheckSum;   // 校驗和16bit 
}attribute((packed))UDP_HEADER, *PUDP_HEADER;

IP數據包結構(20字節):

這裏寫圖片描述
這裏寫圖片描述

1-1.版本4位,表示版本號,目前最廣泛的是4=B1000,即常說的IPv4;相信IPv6以後會廣泛應用,它能給世界上每個鈕釦都分配一個IP地址。

1-2.頭長4位,數據包頭部長度。它表示數據包頭部包括多少個32位長整型,也就是多少個4字節的數據。無選項則爲5(紅色部分)。

1-3.服務類型,包括8個二進制位,每個位的意義如下:

   過程字段:3位,設置了數據包的重要性,取值越大數據越重要,取值範圍爲:0(正常)~ 7(網絡控制)

   延遲字段:1位,取值:0(正常)、1(期特低的延遲)

   流量字段:1位,取值:0(正常)、1(期特高的流量)

   可靠性字段:1位,取值:0(正常)、1(期特高的可靠性)

   成本字段:1位,取值:0(正常)、1(期特最小成本)

   保留字段:1位 ,未使用

1-4.包裹總長16位,當前數據包的總長度,單位是字節。當然最大隻能是65535,及64KB。

2-1.重組標識16位,發送主機賦予的標識,以便接收方進行分片重組。

2-2.標誌3位,他們各自的意義如下:

   保留段位(2):1位,未使用

   不分段位(1):1位,取值:0(允許數據報分段)、1(數據報不能分段)

   更多段位(0):1位,取值:0(數據包後面沒有包,該包爲最後的包)、1(數據包後面有更多的包)

2-3.段偏移量13位,與更多段位組合,幫助接收方組合分段的報文,以字節爲單位。

3-1.生存時間8位,經常ping命令看到的TTL(Time To Live)就是這個,每經過一個路由器,該值就減一,到零丟棄。

3-2.協議代碼8位,表明使用該包裹的上層協議,如TCP=6,ICMP=1,UDP=17等。

3-3.頭檢驗和16位,是IPv4數據包頭部的校驗和。

4-1.源始地址,32位4字節,我們常看到的IP是將每個字節用點(.)分開,如此而已。

5-1.目的地址,32位,同上。

6-1.可選選項,主要是給一些特殊的情況使用,往往安全路由會當作攻擊而過濾掉,普聯(TP_LINK)的TL-ER5110路由就能這麼做。

7-1.用戶數據。

TCP數據包結構(20字節):

這裏寫圖片描述
這裏寫圖片描述
1-1.源始端口16位,範圍當然是0-65535啦。

1-2.目的端口,同上。

2-1.數據序號32位,TCP爲發送的每個字節都編一個號碼,這裏存儲當前數據包數據第一個字節的序號。

3-1.確認序號32位,爲了安全,TCP告訴接受者希望他下次接到數據包的第一個字節的序號。

4-1.偏移4位,類似IP,表明數據距包頭有多少個32位。

4-2.保留6位,未使用,應置零。

4-3.緊急比特URG—當URG=1時,表明緊急指針字段有效。它告訴系統此報文段中有緊急數據,應儘快傳送(相當於高優先級的數據)。

4-3.確認比特ACK—只有當ACK=1時確認號字段纔有效。當ACK=0時,確認號無效。參考TCP三次握手

4-4.復位比特RST(Reset) —當RST=1時,表明TCP連接中出現嚴重差錯(如由於主機崩潰或其他原因),必須釋放連接,然後再重新建立運輸連接。參考TCP三次握手

4-5.同步比特SYN—同步比特SYN置爲1,就表示這是一個連接請求或連接接受報文。參考TCP三次握手

4-6.終止比特FIN(FINal)—用來釋放一個連接。當FIN=1時,表明此報文段的發送端的數據已發送完畢,並要求釋放運輸連接。

4-7.窗口字段16位,窗口字段用來控制對方發送的數據量,單位爲字節。TCP連接的一端根據設置的緩存空間大小確定自己的接收窗口大小,然後通知對方以確定對方的發送窗口的上限。

5-1.包校驗和16位,包括首部和數據這兩部分。在計算檢驗和時,要在TCP報文段的前面加上12字節的僞首部。

5-2.緊急指針16位,緊急指針指出在本報文段中的緊急數據的最後一個字節的序號。

6-1.可選選項24位,類似IP,是可選選項。

6-2.填充8位,使選項湊足32位。

7-1.用戶數據……

也許之前很多人會有疑問,明明我的業務是1M,爲什麼下載速度到100K就飆不上去了?512K的爲什麼50多K就封頂了?… 這裏所說的1M是指1Mbps ,也就是1M比特每秒,即一秒鐘傳輸1048576個二進制位。我們知道一個字節是8個二進制位,即 1M=1048756÷8=131072÷1024=128K。那也應該有128K啊,爲什麼下載速度還是很少到120K,110K都謝天謝地了。看到這裏,你的帳就對了……

可以看出,每個IP包至少要20字節的頭部長度,這些與下載內容無關,加上目前多數傳輸,包括http協議(就是IE直接下載),都是基於TCP協議的,所以IP包裹還要從用戶數據中扣除20字節的TCP包頭,這裏已經是40字節,加上其他程序的連接,狀態確認等等包裹,因而算出來要比理論值要小。另外網絡環境(包括穩定因素和傳輸節點的轉發率)也是影響下載速度的重要原因…

wireshark抓包分析

通過wireshark獲取的tcp數據包如下(包頭一般是:鏈路層14字節,IP20字節,TCP20字節/UDP8字節):

00 07 ed ff 06 00 00 0f

ea fd 9f 96 08 00 45 00

00 29 38 13 40 00 40 06

7d 60 c0 a8 02 0a c0 a8

02 01 18 98 00 17 37 8d

49 3b 00 46 74 e0 50 18

fe d9 ea f7 00 00 32

下面將對其做具體分析。

1、MAC包頭

MAC包頭佔有14字節,即:

00 07 ed ff 06 00 00 0f ea fd 9f 96 08 00

很容易看出來 00 07 ed ff 06 00 和 00 0f ea fd 9f 96 分別是目的MAC地址和源MAC地址,後面的 08 00,代表type是ipv4(0800)

2、IP包頭

IP包頭佔有20個字節,即:

45 00 00 29 38 13 40 00 40 06 7d 60 c0 a8 02 0a c0 a8 02 01

(1) “45”,其中“4”是IP協議的版本(Version),說明是IP4。“5”是IHL(Internet Header Length)位,表示IP頭部的長度,是一個4bit字段,最大就是1111了,值爲12。而這裏爲“5”,說明是20字節,這是標準的IP頭部長度,頭部報文中沒有發送可選部分數據。

(2) “00”,服務類型(Type of Service)。這個8bit字段由3bit的優先權子字段(現在已經被忽略),第8比特保留未用。第4至第7 bit置1時分別代表要求最小時延、最大吞吐量、最高可靠性和最小費用,這四個1bit位最多只能有一個爲1,本例中都爲0,表示是一般服務。 服務類型字段聲明瞭數據報被網絡系統傳輸時可以被怎樣處理。例如:TELNET協議可能要求有最小的延遲,FTP協議(數據)可能要求有最大吞吐量,SNMP協議可能要求有最高可靠性,NNTP(Network News Transfer Protocol,網絡新聞傳輸協議)可能要求最小費用,而ICMP協議可能無特殊要求(4比特全爲0)。實際上,大部分主機會忽略這個字段,但一些動態路由協議如OSPF(Open Shortest Path First Protocol)、IS-IS(Intermediate System to Intermediate System Protocol)可以根據這些字段的值進行路由決策。

(3) “00 29”,IP數據報文總長,包含頭部以及數據,這裏表示41字節。這41字節由20字節的IP頭部以及21字節的TCP頭構成(最後的一個字節爲數據)。目前最大的IP數據包長度是65535字節。

(4) “38 13”,兩個字節的標誌位,用來唯一地標識主機發送的每一份數據報。通常每發一份報文,它的值會加1。

(5) “40”,轉換爲二進制就是“0100 0000”,其中第一位是IP協議目前沒有用上的,爲0。接着的是兩個標誌DF和MF。DF爲1表示不要分段,MF爲1表示還有進一步的分段(本例爲0)。然後的“0 0000”是分段偏移(Fragment Offset)。

(6) “00”,待定。

(7) “40”這個字節就是TTL(Time To Live)了,表示一個IP數據流的生命週期,用Ping顯示的結果,能得到TTL的值,很多文章就說通過TTL位來判別主機類型。因爲一般主機都有默認的TTL值,不同系統的默認值不一樣。比如WINDOWS爲128。不過,一般Ping得到的都不是默認值,這是因爲每次IP數據包經過一個路由器的時候TTL就減一,當減到0時,這個數據包就消亡了。這也時Tracert的原理。本例中爲“40”,轉換爲十進制就是64了,我用的WinXP。

(8) “06”,這個字節表示傳輸層的協議類型(Protocol)。在RFC790中有定義,6表示傳輸層是TCP協議。

(9) “7d 60”這個16bit是頭校驗和(Header Checksum)。

(10) “c0 a8 02 0a”,這個是源地址,也就是PC的IP地址,轉換爲十進制的IP地址就是:192.168.2.10。

(11) “c0 a8 02 01”,這個是目標地址,也就是DIY_DE2的地址,轉換爲十進制的IP地址就是:192.168.2.1。

3、TCP包頭

TCP包頭佔有20個字節,即:

18 98 00 17 37 8d 49 3b 00 46 74 e0 50 18 fe d9 ea f7 00 00

(1) “18 98”,表示本地端口號,轉換爲十進制就是3368。

(2) “00 17”,表示目標端口號,轉換爲十進制就是23,因爲我是連接TELNET站點,所以,這個就是23。

(3) “37 8d 49 3b”,是順序號(Sequence Number),簡寫爲SEQ。

(4) “00 46 74 e0”,是確認號(Acknowledgment Number),簡寫爲ACKNUM。

(5) “50 18”,轉換爲二進制,“0101 0000 0001 1000”。這兩個字節,總共16bit,有好多東西。第一個4bit“0101”,是TCP頭長,十進制爲5,表示20個字節。接着的6bit現在TCP協議沒有用上,都爲0。最後的6bit“01 1000”是六個重要的標誌。這是兩個計算機數據交流的信息標誌。接收和發送斷根據這些標誌來確定信息流的種類(UA PRSF)。下面是一些介紹:

URG:(Urgent Pointer field significant)緊急指針。用到的時候值爲1,用來處理避免TCP數據流中斷。

ACK:(Acknowledgment fieldsignificant)置1時表示確認號(AcknowledgmentNumber)爲合法,爲0的時候表示數據段不包含確認信息,確認號被忽略。

PSH:(Push Function),PUSH標誌的數據,置1時請求的數據段在接收方得到後就可直接送到應用程序,而不必等到緩衝區滿時才傳送。

RST:(Reset the connection)用於復位因某種原因引起出現的錯誤連接,也用來拒絕非法數據和請求。如果接收到RST位時候,通常發生了某些錯誤。

SYN:(Synchronize sequence numbers)用來建立連接,在連接請求中,SYN=1,ACK=0,連接響應時,SYN=1,ACK=1。即,SYN和ACK來區分Connection Request和Connection Accepted。

FIN:(No more data from sender)用來釋放連接,表明發送方已經沒有數據發送了。

這6個標誌位,對號入座。本例中SYN=0,ACK=1,當然就是表示連接請求了。在分析TCP包頭時候,要注意這兩位的變換。

(6) “fe d9”,窗口值,用來控制實現流量控制。

(7) “ea f7”,檢驗和,TCP的檢驗和是強制的。

(8) “00 00”,緊急指針。

發佈了158 篇原創文章 · 獲贊 134 · 訪問量 42萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章