編程隨記 ---- 拼包程序(二)

編程隨記 ---- 拼包程序(二)

    找來了Richard Stevens的經典著作《TCP/IP祥解 卷1:協議》仔細的
翻閱TCP和IP協議部分。從而發現截獲到的數據包前面包含若干頭:
wpcap Header + Ethernet Header + IP Header + TCP Header + Data
前面已經分析了wpcap的頭部。由於只需要分析TCP數據包,所以以太網包
頭部只需解析一下類型字段,看是不是後面封裝的IP包(類型字段是不是
0800)。然後分析一下IP頭,找到源和目的IP地址。再查看8位協議字段,
看IP包封裝的是否是TCP包,當協議字段的值爲6時,爲TCP包。再相應解析
tcp頭,解析出源和目的IP的端口號,並需要保存seq,ack,flag,已備後
面分析三次握手協議和斷開連接時作準備。
    上述過程很簡單,看了具體的協議內容就可以實現。但是接下來分析
TCP連接過程時則相應比較麻煩些。TCP建立連接過程必須滿足三次握手協
議:
   1、源端發送一個SYN:seq1的TCP包;
   2、目的端收到上面的包後,返回一個SYN:seq2:ack2的TCP包,其中ack2
      值爲seq1+1;
   3、源端收到目的端的TCP包後,再發送一個ack1的TCP包,其中ack1的
      值爲seq2+1。
這樣,經過三個TCP包才能正常建立一個TCP連接。而且這個連接是雙向的,
所以需要對每個方向分別保存數據。顯然可以使用srcIP + desIP + srcPort
+ desPort來唯一標示一個半連接。用socket來簡記。
    而對於每個socket必須標記該狀態,記錄達到那個步驟。
    因此,當發現一個SYN的TCP包時,需要查看以前有沒有該socket,有則
看該socket的狀態,從而來判斷上述協議。
    同樣,斷開連接也需要兩個階段:
   1、源端發送一個FIN:seq1的TCP包;
   2、目的端發送一個ack2的TCP包,其中ack2=seq1+1;
注意,這個階段只是斷開一個方向的連接。如果另外一個方向需要斷開連接
同樣需要上述階段。
    這樣,一個拼包程序的整體框架就有了。下面需要解決的只是細節和性
能問題。


附:(一些頭定義)

/* Ethernet header */
typedef struct sniff_ethernet {
    u_char ether_dhost[ETHER_ADDR_LEN]; /* Destination host address */
    u_char ether_shost[ETHER_ADDR_LEN]; /* Source host address */
    u_short ether_type; /* IP? ARP? RARP? etc */
} tEthernetHead;


/* IPv4 header */
typedef struct ip_header{
 u_char ver:4,
            ihl:4;  // Version (4 bits) + Internet header length (4 bits)
 u_char tos;   // Type of service
 u_short tlen;   // Total length
 u_short identification; // Identification
 u_short flags_fo;  // Flags (3 bits) + Fragment offset (13 bits)
 u_char ttl;   // Time to live
 u_char proto;   // Protocol
 u_short crc;   // Header checksum
 u_char saddr[4];  // Source address
 u_char daddr[4];  // Destination address
 u_int op_pad;   // Option + Padding
}ip_header;

typedef struct udp_header{
 u_short sport;   // Source port
 u_short dport;   // Destination port
 u_short len;   // Datagram length
 u_short crc;   // Checksum
}udp_header;

typedef struct tcphdr {
 u_short th_sport;  /* source port */
 u_short th_dport;  /* destination port */
 u_int th_seq;   /* sequence number */
 u_int th_ack;   /* acknowledgement number */
 u_char th_off:4,  /* data offset */
       th_x2:4;  /* (unused) */
 u_char th_flags;
#define TH_FIN 0x01
#define TH_SYN 0x02
#define TH_RST 0x04
#define TH_PUSH 0x08
#define TH_ACK 0x10
#define TH_URG 0x20
 u_short th_win;   /* window */
 u_short th_sum;   /* checksum */
 u_short th_urp;   /* urgent pointer */
}tcp_header;

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