MAC/IP/TCP/UDP頭結構分析

相關索引:https://blog.csdn.net/knowledgebao/article/details/84626184


目錄

一、MAC幀頭定義

二、IP頭結構的定義

三、TCP頭結構定義

四、UDP頭結構的定義


一、MAC幀頭定義

MAC幀是數據幀的一種。而所謂數據幀,就是數據鏈路層協議數據單元,它包括三部分:幀頭,數據部分,幀尾。其中,幀頭和幀尾包含一些必要的控制信息,比如同步信息、地址信息、差錯控制信息等;數據部分則包含網絡層傳下來的數據,比如ip數據包。

目前,有四種不同格式的以太網幀在使用,它們分別是:

  1. Ethernet II即DIX 2.0:Xerox與DEC、Intel在1982年制定的以太網標準幀格式。Cisco名稱爲:ARPA。
  2. Ethernet 802.3 raw:Novell在1983年公佈的專用以太網標準幀格式。Cisco名稱爲:Novell-Ether。
  3. Ethernet 802.3 SAP:IEEE在1985年公佈的Ethernet 802.3的SAP版本以太網幀格式。Cisco名稱爲:SAP。
  4. Ethernet 802.3 SNAP:IEEE在1985年公佈的Ethernet 802.3的SNAP版本以太網幀格式。Cisco名稱爲:SNAP。

Ethernet II和IEEE802.3的幀格式比較類似,主要的不同點在於前者定義的2字節爲包類型,而後者定義的2字節爲的長度;所幸的是,後者定義的有效長度值與前者定義的有效類型值無一相同,這樣就容易區分兩種幀格式了。如果值大於 1500(0x05DC),說明是以太網類型字段,EthernetII 幀格式。如果值小於等於1500,說明是長度字段,IEEE802.3 幀格式。因此類型字段值最小的是 0x0600。而長度最大爲 1500。

   MAC層要求定界字符之後的內容要在64字節到1518個字節之間,其中包括14字節的目標和源MAC,4字節的CRC32值。並且報文幀之間的傳遞間隔要大於9.6us。

 

類型字段 (2個字節): 用來標誌上一層使用的是什麼協議,以便把收到的MAC幀的數據上交給上一層的這個協議;數據字段 (46-1500): 正式名稱是MAC客戶數據字段最小長度64 字節-18字節的首部和尾部 = 數據字段的最小長度;FCS字段 (4 字節):當數據字段的長度小於 46 字節時,應在數據字段的後面加入整數字節的填充字段,以保證以太網的MAC幀長不小於64 字節;在幀的前面插入的 8 字節中的第一個字段共 7 個字節,是前同步碼,用來迅速實現 MAC幀的比特同步。第二個字段是幀開始定界符,表示後面的信息就是MAC幀。

/*數據幀定義,頭14個字節,尾4個字節*/
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;

typedef struct _MAC_FRAME_TAIL
{
 unsigned int m_sCheckSum;    //數據幀尾校驗和
}__attribute__((packed))MAC_FRAME_TAIL, *PMAC_FRAME_TAIL;

二、IP頭結構的定義

/*IP頭定義,共20個字節*/
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 ;
  • 版本(Version)字段:佔4比特。用來表明IP協議實現的版本號,當前一般爲IPv4,即0100。
  • 報頭長度(Internet Header Length,IHL)字段:佔4比特。因爲頭部長度不固定(Option可選部分不固定),所以需要標識該分組的頭部長度多少,用4bit表示,以4byte爲單位,取值範圍:5-15,即20-40byte(其他字段也是類似的計算方式,因爲bit位是不夠表示該字段的值) 
  • 服務類型(Type of Service ,TOS)字段:佔8比特。其中前3比特爲優先權子字段(Precedence,現已被忽略)。第8比特保留未用。第4至第7比特分別代表延遲、吞吐量、可靠性和花費。當它們取值爲1時分別代表要求最小時延、最大吞吐量、最高可靠性和最小費用。這4比特的服務類型中只能置其中1比特爲1。可以全爲0,若全爲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)可以根據這些字段的值進行路由決策。RFC2474的ToS取消了IP precedence字段而使用了DSCP,QoS裏有描述,給QoS用來打標籤。TOS字段歷史:
  • 總長度字段:佔16比特。指明整個數據報的長度(以字節爲單位,含頭長度)。最大長度爲65535字節。可用總長度減去頭部長度獲得實際報文數據的長度,取值範圍0-65535byte,鏈路只允許1500byte,所以一般都需要MTU分片 。
  • 標誌字段:佔16比特。用來唯一地標識主機發送的每一份數據報。通常每發一份報文,它的值會加1。通常與標記字段和分片偏移字段一起用於IP報文的分片。當原始報文大小超過MTU,那麼就必須將原始數據進行分片。每個被分片的報文大小不得超過MTU,而這個字段還將在同一原始文件被分片的報文上打上相同的標記,一邊接收設備可以識別出屬於同一個報文的分片,“類似於進程號”,有時候電信會用他來識別流量是否是同一臺主機(因爲做了PAT後源ip都是一樣的,雞賊!)

    注意:Ethernet以太網跟802.3以太網有所區別,802.3是由IEEE指定的標準,比較複雜用的比較少,網卡一般兩種都支持。IP數據包的MTU值在各種物理線路環境下對應的MTU取值:(注意:不包含幀頭和尾)

  • 標誌位字段:佔3比特。標誌一份數據報是否要求分段。第1位沒有被使用。第2位D是不分片位(DF),Do not fragment,顧名思義,不要分片,當DF位設置爲1時,表示路由器不能對報文進行分片處理。第3位M表示還有後繼分片(MF),More fragment,多分片,當路由器對報分進行分片時,除了最後一個分片的MF位設置爲0外,其他所有分片的MF位均設置1,以便接收者直到收到MF位爲0的分片爲止

  • 段偏移字段:佔13比特。如果一份數據報要求分段的話,此字段指明該段偏移距原始數據報開始的位置。
  • 生存期(TTL:Time to Live)字段:佔8比特。用來設置數據報最多可以經過的路由器數。由發送數據的源主機設置,通常爲32、64(win7)、128、255(linux)等。每經過一個路由器,其值減1,直到0時該數據報被丟棄。
  • 協議字段:佔8比特。指明IP層所封裝的上層協議類型,如ICMP(1)、IGMP(2) 、TCP(6)、UDP(17)等。
  • 頭部校驗和字段:佔16比特。內容是根據IP頭部計算得到的校驗和碼。計算方法是:對頭部中每個16比特進行二進制反碼求和。(和ICMP、IGMP、TCP、UDP不同,IP不對頭部後的數據進行校驗)。
  • 源IP地址、目標IP地址字段:各佔32比特。用來標明發送IP數據報文的源主機地址和接收IP報文的目標主機地址。
  • 可選項字段:佔32比特。用來定義一些任選項:如記錄路徑、時間戳等。這些選項很少被使用,同時並不是所有主機和路由器都支持這些選項。可選項字段的長度必須是32比特的整數倍,如果不足,必須填充0以達到此長度要求。

三、TCP頭結構定義

/*TCP頭定義,共20個字節*/
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;
/*TCP頭中的選項數據部分定義
kind = 1表示 無操作NOP,無後面的部分
kind = 2表示 maximum segment,後面的Length就是maximum segment選項的長度(以byte爲單位,1+1+內容部分長度)
kind =  3表示 windows scale,後面的Length就是 windows scale選項的長度(以byte爲單位,1+1+內容部分長度)
kind =  4表示 SACK permitted    Length爲2,沒有內容部分
kind =  5表示這是一個SACK包     Length爲2,沒有內容部分
kind =  8表示時間戳,Length爲10,含8個字節的時間戳
*/
typedef struct _TCP_OPTIONS
{
 char m_ckind;            //kind(8bit)
 char m_cLength;          //Length(8bit,整個選項的長度,包含前兩部分)
 char m_cContext[32];     //內容(如果有的話)
}__attribute__((packed))TCP_OPTIONS, *PTCP_OPTIONS;
  • 源端口:源端口和IP地址的作用是標識報文的返回地址。
  • 目的端口:端口指明接收方計算機上的應用程序接口。TCP報頭中的源端口號和目的端口號同IP數據報中的源IP與目的IP唯一確定一條TCP連接。
  • 序號和確認號:是TCP可靠傳輸的關鍵部分。序號是本報文段發送的數據組的第一個字節的序號。在TCP傳送的流中,每一個字節一個序號。e.g.一個報文段的序號爲300,此報文段數據部分共有100字節,則下一個報文段的序號爲400。所以序號確保了TCP傳輸的有序性。確認號,即ACK,指明下一個期待收到的字節序號,表明該序號之前的所有數據已經正確無誤的收到。確認號只有當ACK標誌爲1時纔有效。比如建立連接時,SYN報文的ACK標誌位爲0。
  • 數據偏移/首部長度:4bits。由於首部可能含有可選項內容,因此TCP報頭的長度是不確定的,報頭不包含任何任選字段則長度爲20字節,4位首部長度字段所能表示的最大值爲1111,轉化爲10進製爲15,15*32/8 = 60,故報頭最大長度爲60字節。首部長度也叫數據偏移,是因爲首部長度實際上指示了數據區在報文段中的起始偏移值。
  • 保留:爲將來定義新的用途保留,現在一般置0。
  • 控制位:URG  ACK  PSH  RST  SYN  FIN,共6個,每一個標誌位表示一個控制功能。
  1.  URG:緊急指針標誌,爲1時表示緊急指針有效,爲0則忽略緊急指針。
  2.  ACK:確認序號標誌,爲1時表示確認號有效,爲0表示報文中不含確認信息,忽略確認號字段。
  3.  PSH:push標誌,爲1表示是帶有push標誌的數據,指示接收方在接收到該報文段以後,應儘快將這個報文段交給應用程序,而不是在緩衝區排隊。
  4.  RST:重置連接標誌,用於重置由於主機崩潰或其他原因而出現錯誤的連接。或者用於拒絕非法的報文段和拒絕連接請求。
  5.  SYN:同步序號,用於建立連接過程,在連接請求中,SYN=1和ACK=0表示該數據段沒有使用捎帶的確認域,而連接應答捎帶一個確認,即SYN=1和ACK=1。
  6.  FIN:finish標誌,用於釋放連接,爲1時表示發送方已經沒有數據發送了,即關閉本方數據流。
  • 窗口:滑動窗口大小,用來告知發送端接受端的緩存大小,以此控制發送端發送數據的速率,從而達到流量控制。窗口大小時一個16bit字段,因而窗口大小最大爲65535。
  • 校驗和:奇偶校驗,此校驗和是對整個的 TCP 報文段,包括 TCP 頭部和 TCP 數據,以 16 位字進行計算所得。由發送端計算和存儲,並由接收端進行驗證。
  • 緊急指針:只有當 URG 標誌置 1 時緊急指針纔有效。緊急指針是一個正的偏移量,和順序號字段中的值相加表示緊急數據最後一個字節的序號。 TCP 的緊急方式是發送端向另一端發送緊急數據的一種方式。
  • 選項和填充:最常見的可選字段是最長報文大小,又稱爲MSS(Maximum Segment Size),每個連接方通常都在通信的第一個報文段(爲建立連接而設置SYN標誌爲1的那個段)中指明這個選項,它表示本端所能接受的最大報文段的長度。選項長度不一定是32位的整數倍,所以要加填充位,即在這個字段中加入額外的零,以保證TCP頭是32的整數倍。
  • 數據部分: TCP 報文段中的數據部分是可選的。在一個連接建立和一個連接終止時,雙方交換的報文段僅有 TCP 首部。如果一方沒有數據要發送,也使用沒有任何數據的首部來確認收到的數據。在處理超時的許多情況中,也會發送不帶任何數據的報文段。

四、UDP頭結構的定義

/*UDP頭定義,共8個字節*/

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;

 

  • 端口號:用來表示發送和接受進程。由於 I P層已經把I P數據報分配給T C P或U D P(根據I P首部中協議字段值),因此T C P端口號由T C P來查看,而 U D P端口號由UDP來查看。T C P端口號與UDP端口號是相互獨立的。
  • 長度:UDP長度字段指的是UDP首部和UDP數據的字節長度。該字段的最小值爲 8字節(發送一份0字節的UDP數據報是 O K)。
  • 檢驗和:UDP檢驗和是一個端到端的檢驗和。它由發送端計算,然後由接收端驗證。其目的是爲了發現UDP首部和數據在發送端到接收端之間發生的任何改動。整個UDP報文頭和UDP所帶的數據的校驗和(也包括僞報文頭)。僞報文頭不包括在真正的UDP報文頭中,但是它可以保證UDP數據被正確的主機收到了。因在校驗和中加入了僞頭標,故ICMP除能防止單純數據差錯之外,對IP分組也具有保護作用。

參考資料:

1,https://blog.csdn.net/mrwangwang/article/details/8537775

2,https://blog.csdn.net/hhpingyear/article/details/80216680

3,https://www.cnblogs.com/shenpengyan/p/5912567.html

4,http://blog.51cto.com/lidongfeng/2066272

5,  http://blog.51cto.com/lidongfeng/2066278

6,https://wenku.baidu.com/view/d4043a39bd64783e09122bb3.html

7,https://baike.baidu.com/item/%E5%B8%A7%E6%A0%BC%E5%BC%8F/5921425


有任何問題,請聯繫[email protected]

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章