TCP/IP協議頭部結構體(網摘小結)

TCP/IP協議頭部結構體(轉) http://www.cnblogs.com/lancidie/archive/2013/05/16/3082378.html 

網絡協議結構體定義

  1. // i386 is little_endian.   
  2. #ifndef LITTLE_ENDIAN   
  3. #define LITTLE_ENDIAN   (1)   //BYTE ORDER   
  4. #else   
  5. #error Redefine LITTLE_ORDER   
  6. #endif   
  7. //Mac頭部,總長度14字節   
  8. typedef struct _eth_hdr  
  9. {  
  10.     unsigned char dstmac[6]; //目標mac地址   
  11.     unsigned char srcmac[6]; //源mac地址   
  12.     unsigned short eth_type; //以太網類型   
  13. }eth_hdr;  
  14. //IP頭部,總長度20字節   
  15. typedef struct _ip_hdr  
  16. {  
  17.     #if LITTLE_ENDIAN   
  18.     unsigned char ihl:4;     //首部長度   
  19.     unsigned char version:4, //版本    
  20.     #else   
  21.     unsigned char version:4, //版本   
  22.     unsigned char ihl:4;     //首部長度   
  23.     #endif   
  24.     unsigned char tos;       //服務類型   
  25.     unsigned short tot_len;  //總長度   
  26.     unsigned short id;       //標誌   
  27.     unsigned short frag_off; //分片偏移   
  28.     unsigned char ttl;       //生存時間   
  29.     unsigned char protocol;  //協議   
  30.     unsigned short chk_sum;  //檢驗和   
  31.     struct in_addr srcaddr;  //源IP地址   
  32.     struct in_addr dstaddr;  //目的IP地址   
  33. }ip_hdr;  
  34. //TCP頭部,總長度20字節   
  35. typedef struct _tcp_hdr  
  36. {  
  37.     unsigned short src_port;    //源端口號   
  38.     unsigned short dst_port;    //目的端口號   
  39.     unsigned int seq_no;        //序列號   
  40.     unsigned int ack_no;        //確認號   
  41.     #if LITTLE_ENDIAN   
  42.     unsigned char reserved_1:4; //保留6位中的4位首部長度   
  43.     unsigned char thl:4;        //tcp頭部長度   
  44.     unsigned char flag:6;       //6位標誌   
  45.     unsigned char reseverd_2:2; //保留6位中的2位   
  46.     #else   
  47.     unsigned char thl:4;        //tcp頭部長度   
  48.     unsigned char reserved_1:4; //保留6位中的4位首部長度   
  49.     unsigned char reseverd_2:2; //保留6位中的2位   
  50.     unsigned char flag:6;       //6位標誌    
  51.     #endif   
  52.     unsigned short wnd_size;    //16位窗口大小   
  53.     unsigned short chk_sum;     //16位TCP檢驗和   
  54.     unsigned short urgt_p;      //16爲緊急指針   
  55. }tcp_hdr;  
  56. //UDP頭部,總長度8字節   
  57. typedef struct _udp_hdr  
  58. {  
  59.     unsigned short src_port; //遠端口號   
  60.     unsigned short dst_port; //目的端口號   
  61.     unsigned short uhl;      //udp頭部長度   
  62.     unsigned short chk_sum;  //16位udp檢驗和   
  63. }udp_hdr;  
  64. //ICMP頭部,總長度4字節   
  65. typedef struct _icmp_hdr  
  66. {  
  67.     unsigned char icmp_type;   //類型   
  68.     unsigned char code;        //代碼   
  69.     unsigned short chk_sum;    //16位檢驗和   
  70. }icmp_hdr;   

 

 

全面的網絡協議結構體定義

  1. /*********************************************/  
  2. //計算機網絡各種協議的結構   
  3. #define ETHER_ADDR_LEN 6 //NIC物理地址佔6字節   
  4. #define MAXDATA 10240   
  5. /* 
  6. 網絡實驗程序 
  7. 數據包中的TCP包頭,IP包頭,UDP包頭,ARP包,Ethernet包等. 
  8. 以及各種表.路由尋址表,地址解析協議表DNS表等 
  9. */  
  10. #define ETHERTYPE_IP 0x0800   //IP Protocal   
  11. #define ETHERTYPE_ARP 0x0806   //Address Resolution Protocal   
  12. #define ETHERTYPE_REVARP 0x0835   //Reverse Address Resolution Protocal 逆地址解析協議   
  13. /*********************************************/  
  14. //ethernet   
  15. typedef struct ether_header  
  16. {  
  17.     u_char ether_dhost[ETHER_ADDR_LEN];  
  18.     u_char ether_shost[ETHER_ADDR_LEN];  
  19.     u_short ether_type;  
  20. }ETH_HEADER;  
  21. /*********************************************/  
  22. //ether_header eth;   
  23. /*********************************************/  
  24. //arp   
  25. typedef struct arphdr  
  26. {  
  27.     u_short ar_hrd;  
  28.     u_short ar_pro;  
  29.     u_char ar_hln;  
  30.     u_char ar_pln;  
  31.     u_short ar_op;  
  32. }ARP_HEADER;  
  33. /*********************************************/  
  34. /*********************************************/  
  35. //IP報頭   
  36. typedef struct ip  
  37. {  
  38.     u_int ip_v:4; //version(版本)   
  39.     u_int ip_hl:4; //header length(報頭長度)   
  40.     u_char ip_tos;  
  41.     u_short ip_len;  
  42.     u_short ip_id;  
  43.     u_short ip_off;  
  44.     u_char ip_ttl;  
  45.     u_char ip_p;  
  46.     u_short ip_sum;  
  47.     struct in_addr ip_src;  
  48.     struct in_addr ip_dst;  
  49. }IP_HEADER;  
  50. /*********************************************/  
  51. /*********************************************/  
  52. //TCP報頭結構體   
  53. typedef struct tcphdr   
  54. {  
  55.     u_short th_sport;  
  56.     u_short th_dport;  
  57.     u_int th_seq;  
  58.     u_int th_ack;  
  59.     u_int th_off:4;  
  60.     u_int th_x2:4;  
  61.     u_char th_flags;  
  62.     u_short th_win;  
  63.     u_short th_sum;  
  64.     u_short th_urp;  
  65. }TCP_HEADER;  
  66. #define TH_FIN 0x01   
  67. #define TH_SYN 0x02   
  68. #define TH_RST 0x04   
  69. #define TH_PUSH 0x08   
  70. #define TH_ACK 0x10   
  71. #define TH_URG 0x20   
  72. /*********************************************/  
  73. /*********************************************/  
  74. //UDP報頭結構體*/   
  75. typedef struct udphdr   
  76. {  
  77.     u_short uh_sport;  
  78.     u_short uh_dport;  
  79.     u_short uh_ulen;  
  80.     u_short uh_sum;  
  81. }UDP_HEADER;  
  82. /*********************************************/  
  83. //=============================================   
  84. /*********************************************/  
  85. /*ARP與ETHERNET生成的報頭*/  
  86. typedef struct ether_arp  
  87. {  
  88.     struct arphdr ea_hdr;  
  89.     u_char arp_sha[ETHER_ADDR_LEN];  
  90.     u_char arp_spa[4];  
  91.     u_char arp_tha[ETHER_ADDR_LEN];  
  92.     u_char arp_tpa[4];  
  93. }ETH_ARP;  
  94. #define arp_hrd ea_hdr.ar_hrd   
  95. #define arp_pro ea_hdr.ar_pro   
  96. #define arp_hln ea_hdr.ar_hln   
  97. #define arp_pln ea_hdr.ar_pln   
  98. #define arp_op ea_hdr.ar_op   
  99. #define ARPHRD 1   
  100. /*********************************************/  
  101. /*********************************************/  
  102. //tcp與ip生成的報頭   
  103. typedef struct packet_tcp   
  104. {  
  105.     struct ip ip;  
  106.     struct tcphdr tcp;  
  107.     u_char data[MAXDATA];  
  108. }TCP_IP;  
  109. /*********************************************/  
  110. /*********************************************/  
  111. //udp與ip生成的報頭   
  112. typedef struct packet_udp   
  113. {  
  114.     struct ip ip;  
  115.     struct udphdr udp;  
  116. }UDP_IP;  
  117. /*********************************************/  
  118. /*********************************************/  
  119. //ICMP的各種形式   
  120. //icmpx,x==icmp_type;   
  121. //icmp報文(能到達目的地,響應-請求包)   
  122. struct icmp8   
  123. {  
  124.     u_char icmp_type; //type of message(報文類型)   
  125.     u_char icmp_code; //type sub code(報文類型子碼)   
  126.     u_short icmp_cksum;  
  127.     u_short icmp_id;  
  128.     u_short icmp_seq;  
  129.     char icmp_data[1];  
  130. };  
  131. //icmp報文(能返回目的地,響應-應答包)   
  132. struct icmp0   
  133. {  
  134.     u_char icmp_type; //type of message(報文類型)   
  135.     u_char icmp_code; //type sub code(報文類型子碼)   
  136.     u_short icmp_cksum;  
  137.     u_short icmp_id;  
  138.     u_short icmp_seq;  
  139.     char icmp_data[1];  
  140. };  
  141. //icmp報文(不能到達目的地)   
  142. struct icmp3   
  143. {  
  144.     u_char icmp_type; //type of message(報文類型)   
  145.     u_char icmp_code; //type sub code(報文類型子碼),例如:0網絡原因不能到達,1主機原因不能到達...   
  146.     u_short icmp_cksum;  
  147.     u_short icmp_pmvoid;  
  148.     u_short icmp_nextmtu;  
  149.     char icmp_data[1];  
  150. };  
  151. //icmp報文(重發結構體)   
  152. struct icmp5   
  153. {  
  154.     u_char icmp_type; //type of message(報文類型)   
  155.     u_char icmp_code; //type sub code(報文類型子碼)   
  156.     u_short icmp_cksum;  
  157.     struct in_addr icmp_gwaddr;  
  158.     char icmp_data[1];  
  159. };  
  160. struct icmp11   
  161. {  
  162.     u_char icmp_type; //type of message(報文類型)   
  163.     u_char icmp_code; //type sub code(報文類型子碼)   
  164.     u_short icmp_cksum;  
  165.     u_int icmp_void;  
  166.     char icmp_data[1];  
  167. };  

 

 

================================================================================

IP協議 

  IP協議(Internet Protocol)是網絡層協議,用在因特網上,TCP,UDP,ICMP,IGMP數據都是按照IP數據格式發送得。IP協議提供的是不可靠無連接得服務。IP數據包由一個頭部和一個正文部分構成。正文主要是傳輸的數據,我們主要來理解頭部數據,可以從其理解到IP協議。  

IP數據包頭部格式(RFC791) 
 

  Example Internet Datagram Header 

  上面的就是IP數據的頭部格式,這裏大概地介紹一下。  

  IP頭部由20字節的固定長度和一個可選任意長度部分構成,以大段點機次序傳送,從左到 右。  

TCP協議  

  TCP協議(TRANSMISSION CONTROL PROTOCOL)是傳輸層協議,爲應用層提供服務,和UDP不同的是,TCP協議提供的可靠的面向連接的服務。在RFC793中是基本的TCP描述。關於TCP協議的頭部格式內容的說明:  

TCP Header FORMat  
 
 
  TCP Header FORMat  

  跟IP頭部差不多,基本的長度也是20字節。TCP數據包是包含在一個IP數據報文中的。  

  好了,簡單介紹到此爲止。來看看我捕獲的例子吧。這是一次FTP的連接,呵呵,是cuteftp默認的cuteftp的FTP站點,IP地址是:216.3.226.21。我的IP地址假設爲:192.168.1.1。下面的數據就是TCO/IP連接過程中的數據傳輸。我們可以分析TCP/IP協議數據格式以及TCP/IP連接的三次握手(ThreeWay-Handshake)情況。下面的這些十六進制數據只是TCP/IP協議的數據,不是完整的網絡通訊數據。  

  第一次,我向FTP站點發送連接請求(我把TCP數據的可選部分去掉了) 

  192.168.1.1->216.3.226.21  

  IP頭部: 45 00 00 30 52 52 40 00 80 06 2c 23 c0 a8 01 01 d8 03 e2 15  

  TCP頭部:0d 28 00 15 50 5f a9 06 00 00 00 00 70 02 40 00 c0 29 00 00  

  來看看IP頭部的數據是些什麼。  

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

  接下來的一個字節“00”是服務類型(Type of Service)。這個8bit字段由3bit的優先權子字段(現在已經被忽略),4 bit的TOS子字段以及1 bit的未用字段(現在爲0)構成.4 bit的TOS子字段包含:最小延時、最大吞吐量、最高可靠性以及最小費用構成,這四個1bit位最多只能有一個爲1,本例中都爲0,表示是一般服務。  

  接着的兩個字節“00 30”是IP數據報文總長,包含頭部以及數據,這裏表示48字節。這48字節由20字節的IP頭部以及28字節的TCP頭構成(本來截取的TCP頭應該是28字節的,其中8字節爲可選部分,被我省去了)。因此目前最大的IP數據包長度是65535字節。  

  再是兩個字節的標誌位(Identification):“5252”,轉換爲十進制就是21074。這個是讓目的主機來判斷新來的分段屬於哪個分組。  

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

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

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

  “2c 23”這個16bit是頭校驗和(Header Checksum)。  

  接下來“c0 a8 01 01”,這個就是源地址(Source Address)了,也就是我的IP地址。 

  轉換爲十進制的IP地址就是:192.168.1.1,同樣,繼續下來的32位“d8 03 e2 15”是目標地址,216.3.226.21  

  好了,真累啊,終於看完基本的20字節的IP數據報頭了。繼續看TCP的頭部吧,這個是作爲IP數據包的數據部分傳輸的。  

  TCP頭部:0d 28 00 15 50 5f a9 06 00 00 00 00 70 02 40 00 c0 29 00 00  

  一來就是一個兩字節段“0d 28”,表示本地端口號,轉換爲十進制就是3368。第二個兩字節段“00 15”表示目標端口,因爲我是連接FTP站點,所以,這個就是21啦,十六進制當然就是“00 15”。  

  接下來的四個字節“50 5f a9 06”是順序號(Sequence Number),簡寫爲SEQ,SEQ=1348446470下面的四個字節“00 00 00 00”是確認號(Acknowledgment Number),簡寫爲ACKNUM。  

  繼續兩個字節,“70 02”,轉換爲二進制吧,“0111 0000 0000 0010”。這兩個字節,總共16bit,有好多東西呢。第一個4bit“0111”,是TCP頭長,十進制爲7,表示28個字節(剛纔說了,我省略了8字節的option數據,所以你只看見了20字節)。接着的6bit現在TCP協議沒有用上,都爲0。最後的6bit“00 0010”是六個重要的標誌。這是兩個計算機數據交流的信息標誌。接收和發送斷根據這些標誌來確定信息流的種類。下面是一些介紹:  

  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=1,ACK=0,當然就是表示連接請求了。我們可以注意下面兩個過程的這兩位的變換。  

  後面的“40 00 c0 29 00 00”不講了,呵呵,偷懶了。後面兩次通訊的數據,自己分開看吧。我們看看連接的過程,一些重要地方的變化。  

  第二次,FTP站點返回一個可以連接的信號。  

  216.3.226.21->192.168.1.1  

  IP頭部: 45 00 00 2c c6 be 40 00 6a 06 cd ba d8 03 e2 15 c0 a8 01 01  

  TCP頭部:00 15 0d 28 4b 4f 45 c1 50 5f a9 07 60 12 20 58 64 07 00 00  

  第三次,我確認連接。TCP連接建立起來。  

  192.168.1.1->216.3.226.21  

  IP頭部: 45 00 00 28 52 53 40 00 80 06 2c 2a c0 a8 01 01 d8 03 e2 15  

  TCP頭部:0d 28 00 15 50 5f a9 07 4b 4f 45 c2 50 10 40 b0 5b 1c 00 00  

  好,我們看看整個Threeway_handshake過程。  

  第一步,我發出連接請求,TCP數據爲:SEQ=50 5f a9 06,ACKNUM=00 00 00 00,SYN=1,ACK=0。  

  第二步,對方確認可以連接,TCP數據爲:SEQ=4b 4f 45 c1,ACKNUM=50 5f a9 07,SYN=1,ACK=1。  

  第三步,我確認建立連接。SEQ=50 5f a9 07, ACKNUM=4b 4f45c2,SYN=0,ACK=1。  

  可以看出什麼變化麼?正式建立連接了呢,這些東西是什麼值?  

  我接收從216.3.226.21->192.168.1.1的下一個數據包中:  

  SEQ=4b 4f 45 c2,ACKNUM=50 5f a9 07,SYN=0,ACK=1這些都是很基礎的東西,對於編寫sniffer這樣的東西是必須非常熟悉的。這裏只講解了TCP/IP協議的一點點東西,主要是頭部數據的格式。(T002)

===============================================================================

 

附加圖片,直觀具體,幫助理解

 

 

 

 

 

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