⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 synping.cpp

📁 此程序可以扫描多的IP和端口。另外可以多线程训话扫描
💻 CPP
字号:
// SYNPing.cpp: implementation of the CSYNPing class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "JIEMIAN.h"
#include "SYNPing.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
//Global Various
ABCD psd_header;

CSYNPing::CSYNPing()
{
	
}

CSYNPing::~CSYNPing()
{
	
}

int CSYNPing::Ping(char *dest,int port)
{   	
	struct sockaddr_in sin, sa;     //destination   address  
	SOCKET sockRaw = INVALID_SOCKET, sockListen = INVALID_SOCKET;
	int   IpPort;
	char *IpAddr;    //destination IP address
	IpAddr = dest;
	IpPort = port;
	int datasize, ErrorCode;  
	char SendBuf[128] =   {0};
	char ReSendBuf[128] = {0};
	char RecvBuf[65535] = {0};
	
	IP_HEADER  ip_header;
	TCP_HEADER tcp_header;
	sockRaw = socket(AF_INET , SOCK_RAW , IPPROTO_IP);
	sockListen = socket(AF_INET , SOCK_RAW , IPPROTO_IP);
	BOOL flag = true;  
	ErrorCode = setsockopt(sockRaw, IPPROTO_IP, IP_HDRINCL, (char *)&flag, sizeof(flag));
	if (ErrorCode == SOCKET_ERROR)  
	{
	//	AfxMessageBox("Set IP_HDRINCL Error!\n");
		return 0;
	}
	
	//get local ip address   
	struct hostent *hp;
	unsigned char LocalName[256];
	int iErrorCode = gethostname((char*)LocalName, sizeof(LocalName)-1); 
	hp = gethostbyname((char*)LocalName);
	memcpy(&sa.sin_addr.S_un.S_addr, hp->h_addr_list[0], hp->h_length);  //memcpy( void *dest, const void *src, size_t count );
	sa.sin_family = AF_INET;
	sa.sin_port   = htons(IpPort);
	iErrorCode    = bind(sockListen, (PSOCKADDR)&sa, sizeof(sa));
	
	//设置SOCK_RAW为SIO_RCVALL,以便接收所有的IP包
	DWORD dwBufferLen[10] ;
	DWORD dwBufferInLen = 1 ; 
	DWORD dwBytesReturned = 0 ;
	WSAIoctl(sockListen, SIO_RCVALL, &dwBufferInLen, sizeof(dwBufferInLen), &dwBufferLen, sizeof(dwBufferLen), &dwBytesReturned, NULL, NULL);
	
	//获得目标主机IP
	memset(&sin, 0, sizeof(sin));
	sin.sin_family = AF_INET;
	sin.sin_port   = htons(IpPort);
	if((sin.sin_addr.s_addr = inet_addr(IpAddr)) == INADDR_NONE)
	{
		if((hp = gethostbyname(IpAddr)) != NULL)
		{
			memcpy(&(sin.sin_addr), hp -> h_addr_list[0], hp -> h_length);
			sin.sin_family = hp->h_addrtype;
			printf("sin.sin_addr = %s\n", inet_ntoa(sin.sin_addr));
		}
		else
			;		
	}
	
	//填充IP首部
	ip_header.h_verlen       =(4<<4 | sizeof(ip_header)/sizeof(unsigned long));//高四位IP版本号,低四位首部长度    
	ip_header.total_len      = htons(sizeof(IP_HEADER) + sizeof(TCP_HEADER));     //16位总长度(字节)
	ip_header.ident          = 1;                  //16位标识
	ip_header.frag_and_flags = 0;                      //3位标志位
	ip_header.ttl            = 128;                        //8位生存时间TTL
	ip_header.proto          = IPPROTO_TCP;           //8位协议(TCP,UDP…)
	ip_header.checksum       = 0;                         //16位IP首部校验和  init is 0 
	ip_header.sourceIP       = sa.sin_addr.s_addr;
	ip_header.destIP         = sin.sin_addr.s_addr; 
	
	//填充TCP首部
	tcp_header.th_sport = htons(IpPort);               //源端口号
	tcp_header.th_dport = htons(IpPort);                   //目的端口号
	tcp_header.th_seq   = htonl(SEQ);             //SYN序列号
	tcp_header.th_ack   = 0;            //ACK序列号置为0
	tcp_header.th_lenres= (sizeof(TCP_HEADER)/4<<4|0);         //TCP长度和保留位
	tcp_header.th_flag  = 2;                         //  SYN = 1;ack = 0; means SYN scan 
	tcp_header.th_win   = htons(16384);                    //16位窗口大小 16384=2^14;
	tcp_header.th_urp   = 0;                        //偏移
	tcp_header.th_sum   = 0;                     //校验和
	
	//填充TCP伪首部(用于计算校验和,并不真正发送)
	psd_header.saddr = ip_header.sourceIP;                     //源地址
	psd_header.daddr = ip_header.destIP;                //目的地址
	psd_header.mbz   = 0;
	psd_header.ptcl  = IPPROTO_TCP;             //协议类型
	psd_header.tcpl  = htons(sizeof(tcp_header)); 
	
	//计算TCP校验和,计算校验和时包括TCP pseudo header         
	memcpy(SendBuf, &psd_header, sizeof(psd_header));   
	memcpy(SendBuf + sizeof(psd_header), &tcp_header, sizeof(tcp_header));
	tcp_header.th_sum = checksum((USHORT *)SendBuf, sizeof(psd_header) + sizeof(tcp_header));
	
	//计算IP校验和
	memcpy(SendBuf, &ip_header, sizeof(ip_header));
	memcpy(SendBuf + sizeof(ip_header), &tcp_header, sizeof(tcp_header));
	memset(SendBuf + sizeof(ip_header) + sizeof(tcp_header), 0, 4);
	datasize = sizeof(ip_header) + sizeof(tcp_header);
	ip_header.checksum = checksum((USHORT *)SendBuf, datasize);
	
	//填充发送缓冲区
	memcpy(SendBuf, &ip_header, sizeof(ip_header));
	
	//发送TCP报文
	ErrorCode = sendto(sockRaw, SendBuf, datasize, 0, (struct sockaddr*) &sin, sizeof(sin));                                                                                                                                                     
	if (ErrorCode == SOCKET_ERROR)        
	{ 	CString tt;
	tt.Format("Send Error!!: %d",GetLastError());	
	//AfxMessageBox(tt);
	}
	
	//接收数据
	DWORD timeout = 1000;
	DWORD start   = GetTickCount();
	while(true)
	{
		if((GetTickCount() - start) >= timeout) //计时,1000 ms超时
		{
			printf("Receive TimeOut!");
			break;
		}
		else       //收到包
		{	     	
			memset(RecvBuf, 0, sizeof(RecvBuf));   
			int FromLen = sizeof(sin);
			ErrorCode  = recv(sockListen, RecvBuf, sizeof(RecvBuf), 0);
			
			if (ErrorCode == SOCKET_ERROR) 
				printf("Receive Error!" );
			
			// decode ip packet recived
			IP_HEADER  *iphdr1;
			TCP_HEADER *tcphdr1;
			
			unsigned short     iphdrlen1;
			iphdr1     = (IP_HEADER*)RecvBuf; 
			iphdrlen1  = 4*(iphdr1->h_verlen & 0xf);             
			tcphdr1 = (TCP_HEADER*)(RecvBuf + iphdrlen1);
			
			
			if(iphdr1->sourceIP != sin.sin_addr.s_addr) 
				continue;
			
			if(iphdr1->destIP != sa.sin_addr.s_addr)
				continue;
			
			if(tcphdr1->th_sport != htons(IpPort))
				continue;
			
			if(tcphdr1->th_dport != htons(IpPort))
				continue;
			
			//序列号是否正确
			if((ntohl(tcphdr1->th_ack) != (SEQ+1)) && (ntohl(tcphdr1->th_ack) != SEQ)) 
				continue;
			
			//RST/ACK - 无服务  the port is not open.
			if(tcphdr1->th_flag == 20)
			{
				//	AfxMessageBox("主机存在但不响应");
				if(sockRaw != INVALID_SOCKET)
					closesocket(sockRaw);
				if (sockListen != INVALID_SOCKET)
					closesocket(sockListen);
				sockListen = INVALID_SOCKET;
				sockRaw = INVALID_SOCKET;
				return 1 ;
			}
			
			//SYN/ACK - 扫描到一个端口.the port is open
			if(tcphdr1 ->th_flag == 18)
			{
				//	::PostMessage(threadb->m_hwnd,WM_USER_FIND,v,0);  //return the port which is open
				//	AfxMessageBox("端口开放!");
				//设置rst 信号,发送一个rst信号,以关闭连接
				//填充IP首部
				ip_header.h_verlen       =(4<<4 | sizeof(ip_header)/sizeof(unsigned long));//高四位IP版本号,低四位首部长度    
				ip_header.total_len      = htons(sizeof(IP_HEADER) + sizeof(TCP_HEADER));     //16位总长度(字节)
				ip_header.ident          = 1;                                         //16位标识
				ip_header.frag_and_flags = 0;                                          //3位标志位
				ip_header.ttl            = 128;                                   //8位生存时间TTL
				ip_header.proto          = IPPROTO_TCP;                                //8位协议(TCP,UDP…)
				ip_header.checksum       = 0;                                         //16位IP首部校验和  init is 0 
				ip_header.sourceIP       = sa.sin_addr.s_addr;
				ip_header.destIP         = sin.sin_addr.s_addr; 
				
				//填充TCP首部
				tcp_header.th_sport = htons(IpPort);                                      //源端口号
				tcp_header.th_dport = htons(IpPort);                                      //目的端口号
				tcp_header.th_seq   = htonl(SEQ);                                  //SYN序列号
				tcp_header.th_ack   = 0;                                                 //ACK序列号置为0
				tcp_header.th_lenres= (sizeof(TCP_HEADER)/4<<4|0);                        //TCP长度和保留位
				tcp_header.th_flag  = 4;                                   //SYN 标志  SYN = 1;ack = 0; means SYN scan 
				tcp_header.th_win   = htons(16384);                                           //16位窗口大小 16384=2^14;
				tcp_header.th_urp   = 0;                                                 //偏移
				tcp_header.th_sum   = 0;                                                 //校验和
				
				//填充TCP伪首部(用于计算校验和,并不真正发送)
				psd_header.saddr = ip_header.sourceIP;                                    //源地址
				psd_header.daddr = ip_header.destIP;                                      //目的地址
				psd_header.mbz   = 0;
				psd_header.ptcl  = IPPROTO_TCP;                                            //协议类型
				psd_header.tcpl  = htons(sizeof(tcp_header)); 
				
				//计算TCP校验和,计算校验和时包括TCP pseudo header         
				memcpy(ReSendBuf, &psd_header, sizeof(psd_header));   
				memcpy(ReSendBuf + sizeof(psd_header), &tcp_header, sizeof(tcp_header));
				tcp_header.th_sum = checksum((USHORT *)ReSendBuf, sizeof(psd_header) + sizeof(tcp_header));
				
				//计算IP校验和
				memcpy(ReSendBuf, &ip_header, sizeof(ip_header));
				memcpy(ReSendBuf + sizeof(ip_header), &tcp_header, sizeof(tcp_header));
				memset(ReSendBuf + sizeof(ip_header) + sizeof(tcp_header), 0, 4);
				datasize = sizeof(ip_header) + sizeof(tcp_header);
				ip_header.checksum = checksum((USHORT *)ReSendBuf, datasize);
				
				//填充发送缓冲区
				memcpy(ReSendBuf, &ip_header, sizeof(ip_header));
				
				//发送rst信号,关闭整个过程
				ErrorCode = sendto(sockRaw,ReSendBuf,datasize,0,(struct sockaddr*) &sin,sizeof(sin));                                                                                                                                                     
				if (ErrorCode == SOCKET_ERROR)        
					AfxMessageBox("\nSend Error!!:%d\n",GetLastError()); 
				if(sockRaw != INVALID_SOCKET)
					closesocket(sockRaw);
				if (sockListen != INVALID_SOCKET)
					closesocket(sockListen);
				sockListen = INVALID_SOCKET;
				sockRaw = INVALID_SOCKET;
				return 2;
			}
		}//end  else 
	}//end while 
	
	if(sockRaw != INVALID_SOCKET)
		closesocket(sockRaw);
	if (sockListen != INVALID_SOCKET)
		closesocket(sockListen);
	sockListen = INVALID_SOCKET;
	sockRaw = INVALID_SOCKET;
	return 0;
}


//CheckSum:计算校验和的子函数 
USHORT CSYNPing::checksum(USHORT *buffer, int size) 
{ 
	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);
} 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -