winpcap实现从TCP三次握手到发送http请求

之前的文章我都是贴出了协议的格式,对具体字段没有具体说明,今天在这里补充一下。

[cpp]  view plain  copy
  1. /*                       IP报文格式 
  2. 0            8           16                        32 
  3. +------------+------------+-------------------------+ 
  4. | ver + hlen |  服务类型  |         总长度          | 
  5. +------------+------------+----+--------------------+ 
  6. |           标识位        |flag|   分片偏移(13位)   | 
  7. +------------+------------+----+--------------------+ 
  8. |  生存时间  | 高层协议号 |       首部校验和        | 
  9. +------------+------------+-------------------------+ 
  10. |                   源 IP 地址                      | 
  11. +---------------------------------------------------+ 
  12. |                  目的 IP 地址                     | 
  13. +---------------------------------------------------+ 
  14. */  


版本号(Version)字段标明了IP 协议的版本号,目前的协议版本号为4,下一代IP 协议的版本号为6,占4位。

普通的 IP 头部长度为20 个字节,不包含IP 选项字段,注意:这里的头部长度是以4字节即32位为单位的,所以真正的IP报头长度应该是该值 * 4。占4位

位的服务类型(TOS,Type of Service)字段包括一个3 位的优先权字段(COS,Class of Service),4 位TOS 字段和1 位未用位。4 位TOS 分别代表最小时延、最大吞吐量、最高可靠性和最小费用。一般是置0的。

总长度(Total length)是整个IP 数据报长度,如果上层是TCP协议,则总长度 = IP报头长度 + TCP报头长度 + 数据长度。

标识符(Identification)字段唯一地标识主机发送的每一份数据报。通常每发送一份报文它的值就会加1,我试验的时候没有加一,服务器也能响应。

生存时间(TTL,Time to Live)字段设置了数据包可以经过的路由器数目。一旦经过一个路由器,TTL 值就会减1,当该字段值为0 时,数据包将被丢弃,所以你可以将该置设成最大0xFF。

高层协议号:IP是网络层协议,要为传输层服务,一般来说高层协议有TCP、UDP,还可以是ICMP,因为ICMP也是用IP包发送的。TCP 为6,UDP为17,ICMP为1。

首部校验和(Head checksum):IP 头部的校验和,如果有选项字段,那就要一起校验,在计算校验和时一定先要将其值为0。

最后两项是源主机ip地址和目标主机ip地址。


[cpp]  view plain  copy
  1. /* 
  2.                      TCP 报文 
  3. 0                       16                       32  
  4. +------------------------+-------------------------+ 
  5. |      源端口地址        |      目的端口地址       | 
  6. +------------------------+-------------------------+ 
  7. |                      序列号                      | 
  8. +--------------------------------------------------+ 
  9. |                      确认号                      | 
  10. +------+--------+--------+-------------------------+ 
  11. |HLEN/4| 保留位 |控制位/6|         窗口尺寸        | 
  12. +------+--------+--------+-------------------------+ 
  13. |         校验和         |         应急指针        | 
  14. +------------------------+-------------------------+ 
  15. */  

源端口号:标识主机上发起传送的应用程序;

目的端口:标识主机上传送要到达的应用程序。

顺序号:用来标识从TCP源端向TCP目标端发送的数据字节流,它表示在这个报文段中的第一个数据字节。

确认号:只有ACK标志为1时,确认号字段才有效。它包含目标端所期望收到源端的下一个数据字节。

头部长度:TCP报头的长度,单位是4字节即32位,如果没有选项字段,则TCP报头为20字节,这个地方写20 / 4 = 5。这个字段也叫数据偏移量,表示数据开始的地方。

预留:由跟在数据偏移字段后的6位构成,预留位通常为0。

标志位:(U、A、P、R、S、F):占6位。从左到右依次是URG、ACK、PSH、RST、SYN、FIN。各位的含义如下:
  URG:紧急指针(urgent pointer)有效。
  ACK:确认序号有效。
  PSH:接收方应该尽快将这个报文段交给应用层。
  RST:重建连接。
  SYN:发起一个连接。
  FIN:释放一个连接。
窗口大小:占16比特。此字段用来进行流量控制。单位为字节数,这个值是本机期望一次接收的字节数。

TCP校验和:TCP报头校验和。注意,这个地方要校验的不仅仅是TCP报头数据,而是伪报头 + TCP报头 + TCP数据 这三个数据,很多人在这个地方少了。

紧急指针字段:占16比特。它是一个偏移量,和序号字段中的值相加表示紧急数据最后一个字节的序号。


TCP伪报头

[cpp]  view plain  copy
  1. struct PSDTCP_HEADER  
  2. {   
  3.     byte srcIpAddr[4];     //Source IP address; 32 bits  
  4.     byte dstIpAddr[4];     //Destination IP address; 32 bits   
  5.     byte padding;          //padding  
  6.     byte protocol;         //Protocol; 8 bits  
  7.     byte tcpLen[2];        //TCP length; 16 bits  
  8. } ;  

上面说了,在计算TCP校验和时需要伪报头,主要是要用源 /目的主机的IP地址和运输层网络协议号。其实按照协议分层来说,TCP所在的传输层应该和IP地址所在的网络层是分开的,现在传输层要访问网络层报文中的IP地址,好像违反了规定。

最后就是以太网头了如下:

[cpp]  view plain  copy
  1. struct ETHERNET_HEADER  
  2. {    
  3.     byte dstMacAddr[6];  
  4.     byte srcMacAddr[6];  
  5.     byte ethernetType[2];  
  6. };  
以太网头主要是源主机和目标主机的mac地址以及协议,比如IP或者ARP, 这个地方再强调一点,我们很容易获取源主机的mac地址,但对目标主机就不一定了,假如只是做试验,我们可能知道,但假如我们真的要给外网服务器发送,那就不行了,我们不可能知道百度服务器的mac地址,所以在给外网发送时,目标主机的mac地址应该写网关的mac地址,直接发给网关。网上很多帖子在这个地方说的都很模糊,有些甚至是直接全写0xFF。

我们闭着眼可以画出TCP三次握手的连接图,但是你有没有想过,当经过三次握手建立连接后,数据时怎么传递的,在传递数据的时候那几个标志位是什么,是SYN还是ACK,这个网上资料很少,我是先抓包研究的,最后结果如下:


winpcap实现从TCP三次握手到发送http请求_第1张图片


经抓包分析得知,最后发送数据时发的是ack和psh包,至于为什么是ack和psh,我现在还不知道,等接下来慢慢研究。

我连的是百度的服务器,怎么获取百度服务器的ip地址,我别的文章中有,目的端口是80,源端口是随机的。


[cpp]  view plain  copy
  1. int main()  
  2. {  
  3.     srand(time(0));  
  4.     unsigned short srcPort = rand()%65535;//6382;  
  5.     const char *lpszSrcIp = "10.126.72.37";  
  6.     const char *lpszDstIp = "112.80.248.73";  
  7.     const byte srcMac[] = {0x90, 0x2B, 0x34, 0x9A, 0xC2, 0xBB};//主机mac  
  8.     const byte dstMac[] = {0x00, 0x00, 0x5e, 0x00, 0x01, 0x48}; //网关mac  
  9.   
  10.     char szError[1024];  
  11.     const char *lpszAdapterName = "\\Device\\NPF_{1DDB19E0-EC33-46E2-ACB5-085E87EF6489}";  
  12.     pcap_t *handle = pcap_open_live(lpszAdapterName, 65536, 1, 1000, szError );  
  13.     if ( NULL == handle ) return 0;  
  14.   
  15.     TCP_HEADER tcpHeader;  
  16.     memset(&tcpHeader, 0, sizeof tcpHeader );  
  17.     *(unsigned short *)tcpHeader.srcPort = htons(srcPort);  
  18.     *(unsigned short *)tcpHeader.dstPort = htons(80);  
  19.     *(unsigned int *)tcpHeader.seqNumber = htonl(0x00);  
  20.     *(unsigned int *)tcpHeader.ackNumber = htonl(0x00);  
  21.     tcpHeader.headLen = 5 << 4;   
  22.     tcpHeader.contrl = 1 << 1;  
  23.     *(unsigned short *)tcpHeader.wndSize = htons(0xFFFF);  
  24.   
  25.     PSDTCP_HEADER psdHeader;  
  26.     memset(&psdHeader, 0, sizeof psdHeader);  
  27.     *(unsigned int *)psdHeader.dstIpAddr = inet_addr(lpszSrcIp);  
  28.     *(unsigned int *)psdHeader.srcIpAddr = inet_addr(lpszDstIp);  
  29.     psdHeader.protocol = 0x06;  
  30.     *(unsigned short *)psdHeader.tcpLen = htons(sizeof(TCP_HEADER));  
  31.   
  32.     byte psdPacket[1024];  
  33.     memset(psdPacket, 0, sizeof psdPacket);  
  34.     memcpy( psdPacket, &psdHeader, sizeof psdHeader );  
  35.     memcpy( psdPacket + sizeof psdHeader, &tcpHeader, sizeof tcpHeader );  
  36.   
  37.     *(unsigned short *)tcpHeader.checkSum = CheckSum( (unsigned short*) psdPacket, sizeof psdHeader + sizeof tcpHeader );  
  38.       
  39.     IP_HEADER ipHeader;  
  40.     memset( &ipHeader, 0, sizeof ipHeader );  
  41.     unsigned char versionAndLen = 0x04;  
  42.     versionAndLen <<= 4;  
  43.     versionAndLen |= sizeof ipHeader / 4; //版本 + 头长度  
  44.   
  45.     ipHeader.versionAndHeader = versionAndLen;  
  46.     *(unsigned short *)ipHeader.totalLen = htons( sizeof(IP_HEADER) + sizeof(TCP_HEADER) );   
  47.   
  48.     ipHeader.ttl = 0xFF;  
  49.     ipHeader.hiProtovolType = 0x06;  
  50.   
  51.     *(unsigned int *)(ipHeader.srcIpAddr) = inet_addr(lpszSrcIp);  
  52.     *(unsigned int *)(ipHeader.dstIpAddr) = inet_addr(lpszDstIp);  
  53.     *(unsigned short *)(ipHeader.headerCheckSum) = CheckSum( (unsigned short *)&ipHeader, sizeof ipHeader );  
  54.   
  55.     ETHERNET_HEADER ethHeader;  
  56.     memset(ðHeader, 0, sizeof ethHeader);  
  57.     memcpy(ethHeader.dstMacAddr, dstMac, 6);  
  58.     memcpy(ethHeader.srcMacAddr, srcMac, 6);  
  59.     *(unsigned short *)ethHeader.ethernetType = htons(0x0800);  
  60.   
  61.     byte packet[1024];  
  62.     memset(packet, 0, sizeof packet);  
  63.   
  64.     memcpy(packet, ðHeader, sizeof ethHeader);  
  65.     memcpy(packet + sizeof ethHeader, &ipHeader, sizeof ipHeader);  
  66.     memcpy(packet + sizeof ethHeader + sizeof ipHeader, &tcpHeader, sizeof tcpHeader);  
  67.       
  68.     int size = sizeof ethHeader + sizeof ipHeader + sizeof tcpHeader;  
  69.     pcap_sendpacket(handle, packet, size );  
  70.     printf("%-16s ------SYN-----> %-16s\n", lpszSrcIp, lpszDstIp );  
  71.   
  72.     if ( NULL == handle )  
  73.     {  
  74.         printf("\nUnable to open the adapter. %s is not supported by WinPcap\n");  
  75.         return 0;  
  76.     }  
  77.     byte param[1024];  
  78.     memset(param, 0x00, sizeof param );  
  79.     memcpy(param, &srcPort, sizeof srcPort );  
  80.     memcpy(param + sizeof srcPort, handle, 512 );  
  81.     pcap_loop( handle, -1, HandlePacketCallBack, param );  
  82.     pcap_close(handle);   
  83.     return 0;  
  84. }  

main函数先发起连接请求,即就是三次握手的第一步,然后开始抓包,如果抓到服务器回过来的SYN + ACK包,就表明服务器完成了第二次握手,接着向服务器再次发送ACK即就是第三次握手数据包,这样便建立了连接,然后可以向服务器发送HTTP请求,等待服务器回应。将适配器句柄和本地端口作为参数传给回调函数,用来发包和过滤。

[cpp]  view plain  copy
  1. void HandlePacketCallBack(unsigned char *param,const struct pcap_pkthdr* packet_header, const unsigned char *recvPacket)  
  2. {  
  3.     unsigned short localPort = *(unsigned short *)param;  
  4.   
  5.     ETHERNET_HEADER *pEthHeader = ( ETHERNET_HEADER *)recvPacket;  
  6.     if ( *((unsigned short *)(pEthHeader->ethernetType)) != htons(0x0800) ) return;  
  7.   
  8.     IP_HEADER *pIpHeader = ( IP_HEADER *)(recvPacket + sizeof(ETHERNET_HEADER) );  
  9.     if ( pIpHeader->hiProtovolType != 0x06 ) return;  
  10.   
  11.     TCP_HEADER *pTcpHeader = ( TCP_HEADER *)(recvPacket + sizeof(ETHERNET_HEADER) + sizeof(IP_HEADER) );  
  12.     if ( *(unsigned short *)(pTcpHeader->dstPort) != htons(localPort) ) return ;  
  13.   
  14.     //////////////////////////////////////////////////////////////////////  
  15.     IP_HEADER ipHeader;  
  16.     memset( &ipHeader, 0, sizeof ipHeader );  
  17.     unsigned char versionAndLen = 0x04;  
  18.     versionAndLen <<= 4;  
  19.     versionAndLen |= sizeof ipHeader / 4; //版本 + 头长度  
  20.   
  21.     ipHeader.versionAndHeader = versionAndLen;  
  22.     *(unsigned short *)ipHeader.totalLen = htons( sizeof(IP_HEADER) + sizeof(TCP_HEADER) );   
  23.   
  24.     ipHeader.ttl = 0xFF;  
  25.     ipHeader.hiProtovolType = 0x06;  
  26.   
  27.     memcpy(ipHeader.srcIpAddr, pIpHeader->dstIpAddr, sizeof(unsigned int) );  
  28.     memcpy(ipHeader.dstIpAddr, pIpHeader->srcIpAddr, sizeof(unsigned int) );  
  29.   
  30.     *(unsigned short *)(ipHeader.headerCheckSum) = CheckSum( (unsigned short *)&ipHeader, sizeof ipHeader );  
  31.   
  32.     ////////////////////////////////////////////////////////////////////  
  33.     unsigned int ack = ntohl(*(unsigned int *)(pTcpHeader->seqNumber));  
  34.     unsigned int seq =  ntohl(*(unsigned int *)(pTcpHeader->ackNumber));  
  35.   
  36.     TCP_HEADER tcpHeader;  
  37.     memset(&tcpHeader, 0, sizeof tcpHeader );  
  38.     *(unsigned short *)tcpHeader.srcPort = htons(localPort);  
  39.     *(unsigned short *)tcpHeader.dstPort = htons(80);  
  40.     *(unsigned int *)tcpHeader.seqNumber = htonl(seq);  
  41.     *(unsigned int *)tcpHeader.ackNumber = htonl(ack + 1);  
  42.     tcpHeader.headLen = 5 << 4;   
  43.     tcpHeader.contrl = 0x01 << 4; //  
  44.     *(unsigned short *)tcpHeader.wndSize = htons(0xFFFF);  
  45.   
  46.     ///////////////////////////////////////////////////////////////////  
  47.     PSDTCP_HEADER psdHeader;  
  48.     memset(&psdHeader, 0x00, sizeof psdHeader);  
  49.     psdHeader.protocol = 0x06;  
  50.     *(unsigned short *)psdHeader.tcpLen = htons(sizeof(TCP_HEADER));  
  51.     memcpy(psdHeader.dstIpAddr, ipHeader.dstIpAddr, sizeof(unsigned int) );  
  52.     memcpy(psdHeader.srcIpAddr, ipHeader.srcIpAddr, sizeof(unsigned int) );  
  53.   
  54.     byte psdPacket[1024];  
  55.     memcpy( psdPacket, &psdHeader, sizeof psdHeader );  
  56.     memcpy( psdPacket + sizeof psdHeader, &tcpHeader, sizeof tcpHeader );  
  57.   
  58.     *(unsigned short *)tcpHeader.checkSum = CheckSum( (unsigned short*) psdPacket, sizeof psdHeader + sizeof tcpHeader );  
  59.   
  60.     ETHERNET_HEADER ethHeader;  
  61.     memset(ðHeader, 0, sizeof ethHeader);  
  62.     memcpy(ethHeader.dstMacAddr, pEthHeader->srcMacAddr, 6);  
  63.     memcpy(ethHeader.srcMacAddr, pEthHeader->dstMacAddr, 6);  
  64.     *(unsigned short *)ethHeader.ethernetType = htons(0x0800);  
  65.   
  66.     byte packet[1024];  
  67.     memset(packet, 0, sizeof packet);  
  68.   
  69.     memcpy(packet, ðHeader, sizeof ethHeader);  
  70.     memcpy(packet + sizeof ethHeader, &ipHeader, sizeof ipHeader);  
  71.     memcpy(packet + sizeof ethHeader + sizeof ipHeader, &tcpHeader, sizeof tcpHeader);  
  72.   
  73.     int size = sizeof ethHeader + sizeof ipHeader + sizeof tcpHeader;  
  74.   
  75.     pcap_t *handle = (pcap_t*)(param + sizeof(unsigned short));  
  76.   
  77.     byte data[] = "GET / HTTP/1.1\r\n\r\n";  
  78.   
  79.     char srcIp[32], dstIp[32];  
  80.     byte ctrl = pTcpHeader->contrl & 0x3F;  
  81.     switch ( ctrl )  
  82.     {  
  83.     case 0x01 << 1: //syn  
  84.         break;  
  85.     /*case 0x01 << 4: //ack 
  86.         puts("收到ack"); 
  87.         break;*/  
  88.     case ((0x01 << 4) | (0x01 << 1)): //syn+ack  
  89.   
  90.         FormatIpAddr(*(unsigned int *)(pIpHeader->srcIpAddr), srcIp );  
  91.         FormatIpAddr(*(unsigned int *)(pIpHeader->dstIpAddr), dstIp );  
  92.         printf("%-16s ---SYN + ACK--> %-16s\n", srcIp, dstIp );  
  93.   
  94.         ///////////////////////////////////////////////////////////  
  95.   
  96.         pcap_sendpacket(handle, packet, size );  
  97.         FormatIpAddr(*(unsigned int *)ipHeader.srcIpAddr, srcIp );  
  98.         FormatIpAddr(*(unsigned int *)ipHeader.dstIpAddr, dstIp );  
  99.         printf("%-16s ------ACK-----> %-16s\n", srcIp, dstIp );  
  100.   
  101.         Sleep(10);  
  102.   
  103.         pIpHeader = (IP_HEADER *)(packet + sizeof(ETHERNET_HEADER) );  
  104.         *(unsigned short *)(pIpHeader->totalLen) = htons(sizeof(IP_HEADER) + sizeof(TCP_HEADER) + sizeof data );  
  105.         memset(pIpHeader->headerCheckSum, 0x00, sizeof(unsigned short) );  
  106.         *(unsigned short *)(pIpHeader->headerCheckSum) = CheckSum( (unsigned short *)pIpHeader, sizeof(IP_HEADER) );  
  107.   
  108.         pTcpHeader = (TCP_HEADER *)(packet + sizeof(ETHERNET_HEADER) + sizeof(IP_HEADER));  
  109.         pTcpHeader->contrl = 0x01 << 4;  
  110.         *(unsigned int *)(pTcpHeader->ackNumber) = htonl(ack+1);  
  111.         *(unsigned int *)(pTcpHeader->seqNumber) = htonl(seq);  
  112.         memset( pTcpHeader->checkSum, 0x00, sizeof(unsigned short) );  
  113.   
  114.         memset( psdPacket, 0x00, sizeof psdPacket );  
  115.         *(unsigned short *)psdHeader.tcpLen = htons(sizeof(TCP_HEADER) + sizeof(data));  
  116.   
  117.         memcpy( psdPacket, &psdHeader, sizeof psdHeader );  
  118.         memcpy( psdPacket + sizeof psdHeader, pTcpHeader, sizeof(TCP_HEADER) );  
  119.         memcpy( psdPacket + sizeof psdHeader + sizeof(TCP_HEADER), data, sizeof data );  
  120.   
  121.         *(unsigned short *)(pTcpHeader->checkSum) = CheckSum( (unsigned short*) psdPacket, sizeof psdHeader + sizeof(TCP_HEADER) + sizeof data );  
  122.   
  123.         memcpy(packet, ðHeader, sizeof ethHeader);  
  124.         memcpy(packet + sizeof(ETHERNET_HEADER), pIpHeader, sizeof(IP_HEADER) );  
  125.         memcpy(packet + sizeof(ETHERNET_HEADER) + sizeof(IP_HEADER), pTcpHeader, sizeof(TCP_HEADER) );  
  126.         memcpy(packet + sizeof(ETHERNET_HEADER) + sizeof(IP_HEADER)+ sizeof(TCP_HEADER), data, sizeof data );  
  127.           
  128.         size += sizeof data;  
  129.         pcap_sendpacket(handle, packet, size );  
  130.           
  131.         break;        
  132.     default:  
  133.         IP_HEADER *pIpHeader = (IP_HEADER *)(recvPacket + sizeof(ETHERNET_HEADER) );  
  134.         unsigned short ipHeaderLen = pIpHeader->versionAndHeader & 0x0F;  
  135.         ipHeaderLen *= 4;  
  136.         TCP_HEADER *pTcpHeader = (TCP_HEADER *)(recvPacket + sizeof(ETHERNET_HEADER)  + ipHeaderLen );  
  137.   
  138.         int tcpHeaderLen = pTcpHeader->headLen >> 0x04;  
  139.         tcpHeaderLen *= 4;  
  140.         char *str = ( char *)(recvPacket + sizeof(ETHERNET_HEADER) + ipHeaderLen + tcpHeaderLen );  
  141.         puts(str);  
  142.     }  
  143.     return;  
  144. }  

回调函数首先过滤掉非IP数据包,再过滤掉非TCP数据包,再根据端口过滤掉不是自己的TCP数据包。值得注意的就是组包时的包长度和校验和,我就在这个地方耗了很久。

在解析包的时候最好不要直接用sizeof(IP_HEADER)这样类似的写法,而是直接读取报头中的报头长度字段,这样会更精确些,因为我们不用知道服务器有没有添加选项数据。

最后的结果:

winpcap实现从TCP三次握手到发送http请求_第2张图片

最后贴上全部源码

[cpp]  view plain  copy
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <pcap.h>  
  4. #include <winsock2.h>  
  5. #include <iostream>  
  6. using namespace std;  
  7.   
  8. #pragma comment(lib, "../common/lib/Packet.lib")  
  9. #pragma comment(lib, "../common/lib/wpcap.lib")  
  10. #pragma comment(lib, "ws2_32.lib")  
  11.   
  12.   
  13. /*                       IP报文格式 
  14. 0            8           16                        32 
  15. +------------+------------+-------------------------+ 
  16. | ver + hlen |  服务类型  |         总长度          | 
  17. +------------+------------+----+--------------------+ 
  18. |           标识位        |flag|   分片偏移(13位)   | 
  19. +------------+------------+----+--------------------+ 
  20. |  生存时间  | 高层协议号 |       首部校验和        | 
  21. +------------+------------+-------------------------+ 
  22. |                   源 IP 地址                      | 
  23. +---------------------------------------------------+ 
  24. |                  目的 IP 地址                     | 
  25. +---------------------------------------------------+ 
  26. */  
  27.   
  28. struct IP_HEADER  
  29. {  
  30.     byte versionAndHeader;  
  31.     byte serviceType;  
  32.     byte totalLen[2];  
  33.     byte seqNumber[2];  
  34.     byte flagAndFragPart[2];  
  35.     byte ttl;  
  36.     byte hiProtovolType;  
  37.     byte headerCheckSum[2];  
  38.     byte srcIpAddr[4];  
  39.     byte dstIpAddr[4];  
  40. };  
  41.   
  42. /* 
  43.                      TCP 报文 
  44. 0                       16                       32  
  45. +------------------------+-------------------------+ 
  46. |      源端口地址        |      目的端口地址       | 
  47. +------------------------+-------------------------+ 
  48. |                      序列号                      | 
  49. +--------------------------------------------------+ 
  50. |                      确认号                      | 
  51. +------+--------+--------+-------------------------+ 
  52. |HLEN/4| 保留位 |控制位/6|         窗口尺寸        | 
  53. +------+--------+--------+-------------------------+ 
  54. |         校验和         |         应急指针        | 
  55. +------------------------+-------------------------+ 
  56. */  
  57.   
  58. struct TCP_HEADER  
  59. {  
  60.     byte srcPort[2];  
  61.     byte dstPort[2];  
  62.     byte seqNumber[4];  
  63.     byte ackNumber[4];  
  64.     byte headLen;  
  65.     byte contrl;  
  66.     byte wndSize[2];  
  67.     byte checkSum[2];  
  68.     byte uragentPtr[2];  
  69. };  
  70.   
  71. struct PSDTCP_HEADER  
  72. {   
  73.     byte srcIpAddr[4];     //Source IP address; 32 bits  
  74.     byte dstIpAddr[4];     //Destination IP address; 32 bits   
  75.     byte padding;          //padding  
  76.     byte protocol;         //Protocol; 8 bits  
  77.     byte tcpLen[2];        //TCP length; 16 bits  
  78. } ;  
  79.   
  80. struct ETHERNET_HEADER  
  81. {    
  82.     byte dstMacAddr[6];  
  83.     byte srcMacAddr[6];  
  84.     byte ethernetType[2];  
  85. };  
  86.   
  87.   
  88. char *FormatIpAddr( unsigned uIpAddr, char szIp[] )  
  89. {  
  90.     IN_ADDR addr;  
  91.     addr.S_un.S_addr = uIpAddr;  
  92.   
  93.     strcpy( szIp, inet_ntoa( addr ) );  
  94.     return szIp;  
  95. }  
  96.   
  97. unsigned short CheckSum(unsigned short packet[], int size )  
  98. {  
  99.     unsigned long cksum = 0;  
  100.     while (size > 1)   
  101.     {  
  102.         cksum += *packet++;  
  103.         size -= sizeof(USHORT);  
  104.     }  
  105.     if (size)   
  106.     {  
  107.         cksum += *(UCHAR*)packet;  
  108.     }  
  109.     cksum = (cksum >> 16) + (cksum & 0xffff);  
  110.     cksum += (cksum >>16);  
  111.   
  112.     return (USHORT)(~cksum);  
  113. }  
  114.   
  115. void HandlePacketCallBack(unsigned char *param,const struct pcap_pkthdr* packet_header, const unsigned char *recvPacket)  
  116. {  
  117.     unsigned short localPort = *(unsigned short *)param;  
  118.   
  119.     ETHERNET_HEADER *pEthHeader = ( ETHERNET_HEADER *)recvPacket;  
  120.     if ( *((unsigned short *)(pEthHeader->ethernetType)) != htons(0x0800) ) return;  
  121.   
  122.     IP_HEADER *pIpHeader = ( IP_HEADER *)(recvPacket + sizeof(ETHERNET_HEADER) );  
  123.     if ( pIpHeader->hiProtovolType != 0x06 ) return;  
  124.   
  125.     TCP_HEADER *pTcpHeader = ( TCP_HEADER *)(recvPacket + sizeof(ETHERNET_HEADER) + sizeof(IP_HEADER) );  
  126.     if ( *(unsigned short *)(pTcpHeader->dstPort) != htons(localPort) ) return ;  
  127.   
  128.     //////////////////////////////////////////////////////////////////////  
  129.     IP_HEADER ipHeader;  
  130.     memset( &ipHeader, 0, sizeof ipHeader );  
  131.     unsigned char versionAndLen = 0x04;  
  132.     versionAndLen <<= 4;  
  133.     versionAndLen |= sizeof ipHeader / 4; //版本 + 头长度  
  134.   
  135.     ipHeader.versionAndHeader = versionAndLen;  
  136.     *(unsigned short *)ipHeader.totalLen = htons( sizeof(IP_HEADER) + sizeof(TCP_HEADER) );   
  137.   
  138.     ipHeader.ttl = 0xFF;  
  139.     ipHeader.hiProtovolType = 0x06;  
  140.   
  141.     memcpy(ipHeader.srcIpAddr, pIpHeader->dstIpAddr, sizeof(unsigned int) );  
  142.     memcpy(ipHeader.dstIpAddr, pIpHeader->srcIpAddr, sizeof(unsigned int) );  
  143.   
  144.     *(unsigned short *)(ipHeader.headerCheckSum) = CheckSum( (unsigned short *)&ipHeader, sizeof ipHeader );  
  145.   
  146.     ////////////////////////////////////////////////////////////////////  
  147.     unsigned int ack = ntohl(*(unsigned int *)(pTcpHeader->seqNumber));  
  148.     unsigned int seq =  ntohl(*(unsigned int *)(pTcpHeader->ackNumber));  
  149.   
  150.     TCP_HEADER tcpHeader;  
  151.     memset(&tcpHeader, 0, sizeof tcpHeader );  
  152.     *(unsigned short *)tcpHeader.srcPort = htons(localPort);  
  153.     *(unsigned short *)tcpHeader.dstPort = htons(80);  
  154.     *(unsigned int *)tcpHeader.seqNumber = htonl(seq);  
  155.     *(unsigned int *)tcpHeader.ackNumber = htonl(ack + 1);  
  156.     tcpHeader.headLen = 5 << 4;   
  157.     tcpHeader.contrl = 0x01 << 4; //  
  158.     *(unsigned short *)tcpHeader.wndSize = htons(0xFFFF);  
  159.   
  160.     ///////////////////////////////////////////////////////////////////  
  161.     PSDTCP_HEADER psdHeader;  
  162.     memset(&psdHeader, 0x00, sizeof psdHeader);  
  163.     psdHeader.protocol = 0x06;  
  164.     *(unsigned short *)psdHeader.tcpLen = htons(sizeof(TCP_HEADER));  
  165.     memcpy(psdHeader.dstIpAddr, ipHeader.dstIpAddr, sizeof(unsigned int) );  
  166.     memcpy(psdHeader.srcIpAddr, ipHeader.srcIpAddr, sizeof(unsigned int) );  
  167.   
  168.     byte psdPacket[1024];  
  169.     memcpy( psdPacket, &psdHeader, sizeof psdHeader );  
  170.     memcpy( psdPacket + sizeof psdHeader, &tcpHeader, sizeof tcpHeader );  
  171.   
  172.     *(unsigned short *)tcpHeader.checkSum = CheckSum( (unsigned short*) psdPacket, sizeof psdHeader + sizeof tcpHeader );  
  173.   
  174.     ETHERNET_HEADER ethHeader;  
  175.     memset(ðHeader, 0, sizeof ethHeader);  
  176.     memcpy(ethHeader.dstMacAddr, pEthHeader->srcMacAddr, 6);  
  177.     memcpy(ethHeader.srcMacAddr, pEthHeader->dstMacAddr, 6);  
  178.     *(unsigned short *)ethHeader.ethernetType = htons(0x0800);  
  179.   
  180.     byte packet[1024];  
  181.     memset(packet, 0, sizeof packet);  
  182.   
  183.     memcpy(packet, ðHeader, sizeof ethHeader);  
  184.     memcpy(packet + sizeof ethHeader, &ipHeader, sizeof ipHeader);  
  185.     memcpy(packet + sizeof ethHeader + sizeof ipHeader, &tcpHeader, sizeof tcpHeader);  
  186.   
  187.     int size = sizeof ethHeader + sizeof ipHeader + sizeof tcpHeader;  
  188.   
  189.     pcap_t *handle = (pcap_t*)(param + sizeof(unsigned short));  
  190.   
  191.     byte data[] = "GET / HTTP/1.1\r\n\r\n";  
  192.   
  193.     char srcIp[32], dstIp[32];  
  194.     byte ctrl = pTcpHeader->contrl & 0x3F;  
  195.     switch ( ctrl )  
  196.     {  
  197.     case 0x01 << 1: //syn  
  198.         break;  
  199.     /*case 0x01 << 4: //ack 
  200.         puts("收到ack"); 
  201.         break;*/  
  202.     case ((0x01 << 4) | (0x01 << 1)): //syn+ack  
  203.   
  204.         FormatIpAddr(*(unsigned int *)(pIpHeader->srcIpAddr), srcIp );  
  205.         FormatIpAddr(*(unsigned int *)(pIpHeader->dstIpAddr), dstIp );  
  206.         printf("%-16s ---SYN + ACK--> %-16s\n", srcIp, dstIp );  
  207.   
  208.         ///////////////////////////////////////////////////////////  
  209.   
  210.         pcap_sendpacket(handle, packet, size );  
  211.         FormatIpAddr(*(unsigned int *)ipHeader.srcIpAddr, srcIp );  
  212.         FormatIpAddr(*(unsigned int *)ipHeader.dstIpAddr, dstIp );  
  213.         printf("%-16s ------ACK-----> %-16s\n", srcIp, dstIp );  
  214.   
  215.         Sleep(10);  
  216.   
  217.         pIpHeader = (IP_HEADER *)(packet + sizeof(ETHERNET_HEADER) );  
  218.         *(unsigned short *)(pIpHeader->totalLen) = htons(sizeof(IP_HEADER) + sizeof(TCP_HEADER) + sizeof data );  
  219.         memset(pIpHeader->headerCheckSum, 0x00, sizeof(unsigned short) );  
  220.         *(unsigned short *)(pIpHeader->headerCheckSum) = CheckSum( (unsigned short *)pIpHeader, sizeof(IP_HEADER) );  
  221.   
  222.         pTcpHeader = (TCP_HEADER *)(packet + sizeof(ETHERNET_HEADER) + sizeof(IP_HEADER));  
  223.         pTcpHeader->contrl = 0x01 << 4;  
  224.         *(unsigned int *)(pTcpHeader->ackNumber) = htonl(ack+1);  
  225.         *(unsigned int *)(pTcpHeader->seqNumber) = htonl(seq);  
  226.         memset( pTcpHeader->checkSum, 0x00, sizeof(unsigned short) );  
  227.   
  228.         memset( psdPacket, 0x00, sizeof psdPacket );  
  229.         *(unsigned short *)psdHeader.tcpLen = htons(sizeof(TCP_HEADER) + sizeof(data));  
  230.   
  231.         memcpy( psdPacket, &psdHeader, sizeof psdHeader );  
  232.         memcpy( psdPacket + sizeof psdHeader, pTcpHeader, sizeof(TCP_HEADER) );  
  233.         memcpy( psdPacket + sizeof psdHeader + sizeof(TCP_HEADER), data, sizeof data );  
  234.   
  235.         *(unsigned short *)(pTcpHeader->checkSum) = CheckSum( (unsigned short*) psdPacket, sizeof psdHeader + sizeof(TCP_HEADER) + sizeof data );  
  236.   
  237.         memcpy(packet, ðHeader, sizeof ethHeader);  
  238.         memcpy(packet + sizeof(ETHERNET_HEADER), pIpHeader, sizeof(IP_HEADER) );  
  239.         memcpy(packet + sizeof(ETHERNET_HEADER) + sizeof(IP_HEADER), pTcpHeader, sizeof(TCP_HEADER) );  
  240.         memcpy(packet + sizeof(ETHERNET_HEADER) + sizeof(IP_HEADER)+ sizeof(TCP_HEADER), data, sizeof data );  
  241.           
  242.         size += sizeof data;  
  243.         pcap_sendpacket(handle, packet, size );  
  244.           
  245.         break;        
  246.     default:  
  247.         IP_HEADER *pIpHeader = (IP_HEADER *)(recvPacket + sizeof(ETHERNET_HEADER) );  
  248.         unsigned short ipHeaderLen = pIpHeader->versionAndHeader & 0x0F;  
  249.         ipHeaderLen *= 4;  
  250.         TCP_HEADER *pTcpHeader = (TCP_HEADER *)(recvPacket + sizeof(ETHERNET_HEADER)  + ipHeaderLen );  
  251.   
  252.         int tcpHeaderLen = pTcpHeader->headLen >> 0x04;  
  253.         tcpHeaderLen *= 4;  
  254.         char *str = ( char *)(recvPacket + sizeof(ETHERNET_HEADER) + ipHeaderLen + tcpHeaderLen );  
  255.         puts(str);  
  256.     }  
  257.     return;  
  258. }  
  259.   
  260. int main()  
  261. {  
  262.     srand(time(0));  
  263.     unsigned short srcPort = rand()%65535;//6382;  
  264.     const char *lpszSrcIp = "10.126.72.37";  
  265.     const char *lpszDstIp = "112.80.248.73";  
  266.     const byte srcMac[] = {0x90, 0x2B, 0x34, 0x9A, 0xC2, 0xBB};//主机mac  
  267.     const byte dstMac[] = {0x00, 0x00, 0x5e, 0x00, 0x01, 0x48}; //网关mac  
  268.   
  269.     char szError[1024];  
  270.     const char *lpszAdapterName = "\\Device\\NPF_{1DDB19E0-EC33-46E2-ACB5-085E87EF6489}";  
  271.     pcap_t *handle = pcap_open_live(lpszAdapterName, 65536, 1, 1000, szError );  
  272.     if ( NULL == handle ) return 0;  
  273.   
  274.     TCP_HEADER tcpHeader;  
  275.     memset(&tcpHeader, 0, sizeof tcpHeader );  
  276.     *(unsigned short *)tcpHeader.srcPort = htons(srcPort);  
  277.     *(unsigned short *)tcpHeader.dstPort = htons(80);  
  278.     *(unsigned int *)tcpHeader.seqNumber = htonl(0x00);  
  279.     *(unsigned int *)tcpHeader.ackNumber = htonl(0x00);  
  280.     tcpHeader.headLen = 5 << 4;   
  281.     tcpHeader.contrl = 1 << 1;  
  282.     *(unsigned short *)tcpHeader.wndSize = htons(0xFFFF);  
  283.   
  284.     PSDTCP_HEADER psdHeader;  
  285.     memset(&psdHeader, 0, sizeof psdHeader);  
  286.     *(unsigned int *)psdHeader.dstIpAddr = inet_addr(lpszSrcIp);  
  287.     *(unsigned int *)psdHeader.srcIpAddr = inet_addr(lpszDstIp);  
  288.     psdHeader.protocol = 0x06;  
  289.     *(unsigned short *)psdHeader.tcpLen = htons(sizeof(TCP_HEADER));  
  290.   
  291.     byte psdPacket[1024];  
  292.     memset(psdPacket, 0, sizeof psdPacket);  
  293.     memcpy( psdPacket, &psdHeader, sizeof psdHeader );  
  294.     memcpy( psdPacket + sizeof psdHeader, &tcpHeader, sizeof tcpHeader );  
  295.   
  296.     *(unsigned short *)tcpHeader.checkSum = CheckSum( (unsigned short*) psdPacket, sizeof psdHeader + sizeof tcpHeader );  
  297.       
  298.     IP_HEADER ipHeader;  
  299.     memset( &ipHeader, 0, sizeof ipHeader );  
  300.     unsigned char versionAndLen = 0x04;  
  301.     versionAndLen <<= 4;  
  302.     versionAndLen |= sizeof ipHeader / 4; //版本 + 头长度  
  303.   
  304.     ipHeader.versionAndHeader = versionAndLen;  
  305.     *(unsigned short *)ipHeader.totalLen = htons( sizeof(IP_HEADER) + sizeof(TCP_HEADER) );   
  306.   
  307.     ipHeader.ttl = 0xFF;  
  308.     ipHeader.hiProtovolType = 0x06;  
  309.   
  310.     *(unsigned int *)(ipHeader.srcIpAddr) = inet_addr(lpszSrcIp);  
  311.     *(unsigned int *)(ipHeader.dstIpAddr) = inet_addr(lpszDstIp);  
  312.     *(unsigned short *)(ipHeader.headerCheckSum) = CheckSum( (unsigned short *)&ipHeader, sizeof ipHeader );  
  313.   
  314.     ETHERNET_HEADER ethHeader;  
  315.     memset(ðHeader, 0, sizeof ethHeader);  
  316.     memcpy(ethHeader.dstMacAddr, dstMac, 6);  
  317.     memcpy(ethHeader.srcMacAddr, srcMac, 6);  
  318.     *(unsigned short *)ethHeader.ethernetType = htons(0x0800);  
  319.   
  320.     byte packet[1024];  
  321.     memset(packet, 0, sizeof packet);  
  322.   
  323.     memcpy(packet, ðHeader, sizeof ethHeader);  
  324.     memcpy(packet + sizeof ethHeader, &ipHeader, sizeof ipHeader);  
  325.     memcpy(packet + sizeof ethHeader + sizeof ipHeader, &tcpHeader, sizeof tcpHeader);  
  326.       
  327.     int size = sizeof ethHeader + sizeof ipHeader + sizeof tcpHeader;  
  328.     pcap_sendpacket(handle, packet, size );  
  329.     printf("%-16s ------SYN-----> %-16s\n", lpszSrcIp, lpszDstIp );  
  330.   
  331.     if ( NULL == handle )  
  332.     {  
  333.         printf("\nUnable to open the adapter. %s is not supported by WinPcap\n");  
  334.         return 0;  
  335.     }  
  336.     byte param[1024];  
  337.     memset(param, 0x00, sizeof param );  
  338.     memcpy(param, &srcPort, sizeof srcPort );  
  339.     memcpy(param + sizeof srcPort, handle, 512 );  
  340.     pcap_loop( handle, -1, HandlePacketCallBack, param );  
  341.     pcap_close(handle);   
  342.     return 0;  
  343. }  

你可能感兴趣的:(tcp,winpcap)