TCP/IP各種數據包結構體

http://hi.baidu.com/wyw5257/blog/item/9d1e1afaa0bde50da8d31110.html

From:http://blog.csdn.net/hzb1983/archive/2009/06/22/4288530.aspx

http://wenku.baidu.com/view/46c180c7aa00b52acfc7ca0b.html

下面這些TCP/IP數據包是我在進行Socket及Wipcap網絡編程過程中曾經用到過的數據包結構體, 這些東西平時看起來不起眼,真正用到的時候就會覺得非常有用......

/*物理幀頭結構*/
typedef struct {
   BYTE  desmac[6]; //目的MAC地址
   BYTE  srcmac[6]; //源MAC地址
  USHORT  ethertype; //幀類型
}Dlc_Header;      

/*IP報頭結構*/
typedef struct  {
 BYTE  h_len_ver;  //IP版本號(高4位)及以32比特爲單位的IP包頭部的長度(低四位)
 BYTE  tos;      //服務類型TOS
 USHORT total_len; //IP包總長度
 USHORT ident;     //標識
 USHORT frag_and_flags;  //標誌位
 BYTE ttl;      //生存時間
 BYTE proto;    //協議
 USHORT checksum; //IP首部校驗和
 BYTE  sourceip[4]; //源IP地址(32位)
 //或者UINT sourceip;
 BYTE  destip[4];  //目的IP地址(32位)
//或者 UINT  destip;
}Ip_Header;

/*TCP報頭*/
typedef struct {
 USHORT  srcport; // 源端口
 USHORT  dstport; // 目的端口
 UINT  seqnum;  // 順序號
 UINT  acknum;  //期待獲得對方的TCP包編號
 BYTE h_len;  // 以32比特爲單位的TCP報頭長度
 BYTE  flags; // 標誌(URG、ACK等)
 USHORT indow; // 窗口大小
 USHORT chksum; // 校驗和
 USHORT urgptr; // 緊急指針
}Tcp_Header;

//TCP僞首部 用於進行TCP校驗和的計算,保證TCP效驗的有效性
typedef struct{
ULONG sourceip;//源IP地址
ULONG destip;//目的IP地址
BYTE mbz;//置空(0)
BYTE ptcl;//協議類型(IPPROTO_TCP)
USHORT tcpl;//TCP頭的長度(單位:字節)
}PSD_HEADER;

/*UDP報頭*/
typedef struct  {
USHORT srcport; // 源端口
USHORT dstport; // 目的端口
USHORT total_len; // 包括UDP報頭及UDP數據的長度(單位:字節)
USHORT chksum; // 校驗和
}Udp_Header;

//UDP僞首部-僅用於計算校驗和
typedef struct tsd_hdr
{
BYTE sourceip[4]; //源IP地址
BYTE destip[4]; //目的IP地址
BYTE mbz;//置空(0)
BYTE ptcl; //協議類型(IPPROTO_UDP)
USHORT udpl;//UDP包總長度(不包括僞首部的長度 單位:字節)
}PSD_HEADER;


/*ICMP報頭*/
typedef struct {
 BYTE i_type;   //類型 發出的ICMP爲8(ICMP_ECHO_REQUEST),接受到的ICMP爲0
 BYTE i_code;   //代碼
 USHORT i_cksum; //ICMP包校驗和
 USHORT i_id;    //識別號(一般用進程號作爲標識號)
 USHORT i_seq;   //報文序列號(一般設置爲0)
 ULONG timestamp;//時間戳
}Icmp_Header;

//ARP幀結構
typedef struct {
   USHORT HW_Type;//硬件類型Ethernet:0x1
   USHORT Prot_Type;//上層協議類型IP:0x0800
   BYTE HW_Addr_Len;//硬件地址長度:6
   BYTE Prot_Addr_Len;//協議地址(IP地址)的長度:4
   USHORT Flag;//1表示請求,2表示應答
   BYTE Send_HW_Addr[6];//源MAC地址
   BYTE Send_Prot_Addr[4];//源IP地址
   BYTE Targ_HW_Addr[6];//目的MAC地址
   BYTE Targ_Prot_Addr[4];//目的IP地址
   BYTE Padding[18];//填充數據
}Arp_Frame;

/*DNS數據報頭*/
typedef struct {
USHORT id; //標識,通過它客戶端可以將DNS的請求與應答相匹配;
USHORT flags; //標誌:(查詢)0x0100 (應答)0x8180  這些數字都是主機序
USHORT questions; //問題數目
USHORT answers; //資源記錄數目
USHORT author; //授權資源記錄數目
USHORT addition; //額外資源記錄數目
}DNS_HEADER;

//這是DNS包的公共部分,即查詢包及應答包都含有這部分,由於查詢問題(Domain)大小無法確定,因此這裏不好將其及其以後的數據寫入結構體中

 

 

From:http://tech.sina.com.cn/s/2006-11-10/1455153882.shtml

大多數程序員所接觸到的套接字(Socket)爲兩類:

  (1)流式套接字(SOCK_STREAM):一種面向連接的Socket,針對於面向連接的TCP服務應用;

  (2)數據報式套接字(SOCK_DGRAM):一種無連接的Socket,對應於無連接的UDP服務應用。

  從用戶的角度來看,SOCK_STREAM、SOCK_DGRAM這兩類套接字似乎的確涵蓋了TCP/IP應用的全部,因爲基於TCP/IP的應用,從協議棧的層次上講,在傳輸層的確只可能建立於TCP或UDP協議之上(圖1),而SOCK_STREAM、SOCK_DGRAM又分別對應於TCP和 UDP,所以幾乎所有的應用都可以用這兩類套接字實現。


圖1 TCP/IP協議棧

  但是,當我們面對如下問題時,SOCK_STREAM、SOCK_DGRAM將顯得這樣無助:

  (1) 怎樣發送一個自定義的IP包?

  (2) 怎樣發送一個ICMP協議包?

  (3) 怎樣使本機進入雜糅模式,從而能夠進行網絡sniffer?

  (4) 怎樣分析所有經過網絡的包,而不管這樣包是否是發給自己的?

  (5) 怎樣僞裝本地的IP地址?

  這使得我們必須面對另外一個深刻的主題――原始套接字(Raw Socket)。Raw Socket廣泛應用於高級網絡編程,也是一種廣泛的黑客手段。著名的網絡sniffer、拒絕服務攻擊(DOS)、IP欺騙等都可以以Raw Socket實現。

  Raw Socket與標準套接字(SOCK_STREAM、SOCK_DGRAM)的區別在於前者直接置"根"於操作系統網絡核心(Network Core),而SOCK_STREAM、SOCK_DGRAM則"懸浮"於TCP和UDP協議的外圍,如圖2所示:


圖2 Raw Socket與標準Socket

  當我們使用Raw Socket的時候,可以完全自定義IP包,一切形式的包都可以"製造"出來。因此,本文事先必須對TCP/IP所涉及IP包結構進行必要的交待。

  目前,IPv4的報頭結構爲:

版本號(4) 包頭長(4) 服務類型(8)
數據包長度(16)
標識(16)
偏移量(16)
生存時間(8)
傳輸協議(8)
校驗和(16)
源地址(32)

目的地址(32)
 
選項(8)
.........
填充

  對其進行數據結構封裝:

typedef struct _iphdr //定義IP報頭
{
 unsigned char h_lenver; //4位首部長度+4位IP版本號
 unsigned char tos; //8位服務類型TOS
 unsigned short total_len; //16位總長度(字節)
 unsigned short ident; //16位標識
 unsigned short frag_and_flags; //3位標誌位
 unsigned char ttl; //8位生存時間 TTL
 unsigned char proto; //8位協議 (TCP, UDP 或其他)
 unsigned short checksum; //16位IP首部校驗和
 unsigned int sourceIP; //32位源IP地址
 unsigned int destIP; //32位目的IP地址
} IP_HEADER;

  或者將上述定義中的第一字節按位拆分:

typedef struct _iphdr //定義IP報頭
{
 unsigned char h_len : 4; //4位首部長度
 unsigned char ver : 4; //4位IP版本號
 unsigned char tos;
 unsigned short total_len;
 unsigned short ident;
 unsigned short frag_and_flags;
 unsigned char ttl;
 unsigned char proto;
 unsigned short checksum;
 unsigned int sourceIP;
 unsigned int destIP;
} IP_HEADER;

  更加嚴格地講,上述定義中h_len、ver字段的內存存放順序還與具體CPU的Endian有關,因此,更加嚴格的IP_HEADER可定義爲:

typedef struct _iphdr //定義IP報頭
{
 #if defined(__LITTLE_ENDIAN_BITFIELD)
  unsigned char h_len : 4; //4位首部長度
  unsigned char ver : 4; //4位IP版本號
 #elif defined (__BIG_ENDIAN_BITFIELD)
  unsigned char ver : 4; //4位IP版本號
  unsigned char h_len : 4; //4位首部長度
 #endif
 unsigned char tos;
 unsigned short total_len;
 unsigned short ident;
 unsigned short frag_and_flags;
 unsigned char ttl;
 unsigned char proto;
 unsigned short checksum;
 unsigned int sourceIP;
 unsigned int destIP;
} IP_HEADER;

  TCP報頭結構爲:

源端口(16)
目的端口(16)
序列號(32)
確認號(32)
TCP偏移量(4)
保留(6)
標誌(6)
窗口(16)
校驗和(16)
緊急(16)
選項(0或32)
數據(可變)

  對應數據結構:

typedef struct psd_hdr //定義TCP僞報頭
{
 unsigned long saddr; //源地址
 unsigned long daddr; //目的地址
 char mbz;
 char ptcl; //協議類型
 unsigned short tcpl; //TCP長度
}PSD_HEADER;
typedef struct _tcphdr //定義TCP報頭
{
 unsigned short th_sport; //16位源端口
 unsigned short th_dport; //16位目的端口
 unsigned int th_seq; //32位序列號
 unsigned int th_ack; //32位確認號
 unsigned char th_lenres; //4位首部長度/4位保留字
 unsigned char th_flag; //6位標誌位
 unsigned short th_win; //16位窗口大小
 unsigned short th_sum; //16位校驗和
 unsigned short th_urp; //16位緊急數據偏移量
} TCP_HEADER;

  同樣地,TCP頭的定義也可以將位域拆分:

typedef struct _tcphdr
{
 unsigned short th_sport;
 unsigned short th_dport;
 unsigned int th_seq;
 unsigned int th_ack;
 /*little-endian*/
 unsigned short tcp_res1: 4, tcp_hlen: 4, tcp_fin: 1, tcp_syn: 1, tcp_rst: 1, tcp_psh: 1, tcp_ack: 1, tcp_urg: 1, tcp_res2: 2;
 unsigned short th_win;
 unsigned short th_sum;
 unsigned short th_urp;
} TCP_HEADER;

  UDP報頭爲:

源端口(16)
目的端口(16)
報文長(16)
校驗和(16)

  對應的數據結構爲:

typedef struct _udphdr //定義UDP報頭
{
 unsigned short uh_sport;//16位源端口
 unsigned short uh_dport;//16位目的端口
 unsigned short uh_len;//16位長度
 unsigned short uh_sum;//16位校驗和
} UDP_HEADER;

  ICMP協議是網絡層中一個非常重要的協議,其全稱爲Internet Control Message Protocol(因特網控制報文協議),ICMP協議彌補了IP的缺限,它使用IP協議進行信息傳遞,向數據包中的源端節點提供發生在網絡層的錯誤信息反饋。ICMP報頭爲:

類型(8)
代碼(8)
校驗和(16)
消息內容

  常用的回送與或回送響應ICMP消息對應數據結構爲:

typedef struct _icmphdr //定義ICMP報頭(回送與或回送響應)
{
 unsigned char i_type;//8位類型
 unsigned char i_code; //8位代碼
 unsigned short i_cksum; //16位校驗和
 unsigned short i_id; //識別號(一般用進程號作爲識別號)
 unsigned short i_seq; //報文序列號
 unsigned int timestamp;//時間戳
} ICMP_HEADER;

  常用的ICMP報文包括ECHO-REQUEST(響應請求消息)、ECHO-REPLY(響應應答消息)、Destination Unreachable(目標不可到達消息)、Time Exceeded(超時消息)、Parameter Problems(參數錯誤消息)、Source Quenchs(源抑制消息)、Redirects(重定向消息)、Timestamps(時間戳消息)、Timestamp Replies(時間戳響應消息)、Address Masks(地址掩碼請求消息)、Address Mask Replies(地址掩碼響應消息)等,是Internet上十分重要的消息。後面章節中所涉及到的ping命令、ICMP拒絕服務攻擊、路由欺騙都與 ICMP協議息息相關。

  另外,本系列文章中的部分源代碼參考了一些優秀程序員的開源項目,由於篇幅的關係我們不能一一列舉,在此一併表示感謝。
發佈了44 篇原創文章 · 獲贊 3 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章