📄 synping.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 + -