#include
#include
#include
#include
#include
#include "WS2TCPIP.H"
#pragma comment(lib,"Ws2_32.lib")
using namespace std;
//SOCKADDR_IN target, source;
//sockaddr_in target, source;
//int sock;
typedef struct _iphdr
{
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;
//TCP伪首部的作用主要是进行校验和的计算
typedef struct psd_hdr //定义TCP伪首部
{
unsigned long saddr; //源地址
unsigned long daddr; //目的地址
char mbz;
char ptcl; //协议类型
unsigned short tcpl; //TCP长度
}PSDHEADER;
typedef struct _tcphdr //定义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;
#define FINISH 100
#define RUN 200
#define SIO_WSAIOW(IOC_VENDOR,l)
#define SEQ 0x28376839
USHORT CheckSum(USHORT buffer, int size) //CRC校验通用代码
{
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);
}
//************************IP解包******************
/*
int DecodeIPHeader(char recvbuf, int bytes)
{
IPHEADER *iphdr;
TCPHEADER *tcphdr;
unsigned short iphdrlen;
iphdr = (IPHEADER *)recvbuf;
iphdrlen = sizeof(unsigned long) * (iphdr->h_verlen & 0xf);
iphdrlen = sizeof(IPHEADER);
tcphdr = (TCPHEADER)(recvbuf + iphdrlen);
//是否来自目标IP
if (iphdr->sourceIP != target.sin_addr.s_addr) {
printf("不来自目标IP\n");
return 0;
}
//序列号是否正确
if (ntohl(tcphdr->th_ack) != (SEQ + 1)) {
printf("序列号错误\n");
return 0;
}
//RST/ACK - 无服务
if (tcphdr->th_flag == 20) {
printf("RST+ACK 无服务.\n");
return 1;
}
//SYN/ACK - 扫描到一个端口
if (tcphdr->th_flag == 18) {
printf("%d\n", ntohs(tcphdr->th_sport));
return 2;
}
printf("未知\n");
return 1;
}
*/
////////////////////////////////////////////////////////////////////////
void SynScan(string uIP, u_short uPortBegin, u_short uPortEnd)
{
int datasize;
IPHEADER ipHeader;//IP包头
TCPHEADER tcpHeader;//TCP包头
PSDHEADER psdHeader;//伪TCP包头
//**********************扫描顺序***********************
for (u_short port = uPortBegin;port<uPortEnd;port++) //端口顺序
{
//SOCKET sock = INVALID_SOCKET;
//SOCKET sock;
int sock;
SOCKADDR_IN target, source;
WSADATA data;
WORD w = MAKEWORD(2, 2);
WSAStartup(w, &data);
if ((sock = socket(AF_INET, SOCK_RAW, IPPROTO_IP)) == INVALID_SOCKET)
{
cout << "发送原始套接字Socket创建出错" << endl << GetLastError() << endl;
return;
}
//**********************扫描顺序***********************
BOOL flag = true;
if (setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char*)&flag, sizeof(flag)) == SOCKET_ERROR)
{
cout << "套接字选项IP_HDRINCL出错!\n" << endl;
return;
}
//SIO_RCVALL函数是可以读取所有IP数据包的必要设置
DWORD dwBufferLen[10];
DWORD dwBufferInLen = 1;
DWORD dwBytesReturned = 0;
WSAIoctl(sock, _WSAIOW(IOC_VENDOR, 1), &dwBufferInLen, sizeof(dwBufferInLen), &dwBufferLen, sizeof(dwBufferLen), &dwBytesReturned, NULL, NULL);
setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char *)&flag, sizeof(flag));
source.sin_family = AF_INET;
source.sin_port = htons(53638);
source.sin_addr.s_addr = inet_addr("10.15.57.28");//本机IP地址
if (bind(sock, (PSOCKADDR)&source, sizeof(source)) == SOCKET_ERROR)
cout << "绑定本地IP接收出错。" << endl;
target.sin_family = AF_INET;
target.sin_addr.s_addr = inet_addr(uIP.c_str()); //对方IP
target.sin_port = htons(port); //对方端口
cout << uIP.c_str() << endl;
//分别自己填充IP头、TCP头、伪IP头,并计算其中的校验和
char SendBuf[1024] = { 0 };
//设置IP包头
ipHeader.h_verlen = (4 << 4 | sizeof(ipHeader) / sizeof(unsigned long));
ipHeader.tos = 0;
ipHeader.total_len = htons(sizeof(ipHeader) + sizeof(tcpHeader));
ipHeader.ident = 1;
ipHeader.frag_and_flags = 0;
ipHeader.ttl = 128;
ipHeader.proto = IPPROTO_TCP;
ipHeader.checksum = 0;
ipHeader.sourceIP = source.sin_addr.s_addr;
ipHeader.destIP = target.sin_addr.s_addr;
//设置TCP头
tcpHeader.th_sport = source.sin_port; //本地端口
tcpHeader.th_dport = target.sin_port; //目标端口
tcpHeader.th_seq = htonl(SEQ);
tcpHeader.th_ack = 0;
tcpHeader.th_lenres = (sizeof(tcpHeader) / 4 << 4 | 0);
tcpHeader.th_flag = 2; //2为SYN,1为FIN,16为ACK
tcpHeader.th_win = htons(16384);
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(SendBuf, &psdHeader, sizeof(psdHeader));
memcpy(SendBuf + sizeof(psdHeader), &tcpHeader, sizeof(tcpHeader));
tcpHeader.th_sum = CheckSum((USHORT *)SendBuf, sizeof(psdHeader) + sizeof(tcpHeader));
memcpy(SendBuf, &ipHeader, sizeof(ipHeader));
memcpy(SendBuf + sizeof(ipHeader), &tcpHeader, sizeof(tcpHeader));
memset(SendBuf + sizeof(ipHeader) + sizeof(tcpHeader), 0, 4);
ipHeader.checksum = CheckSum((USHORT*)SendBuf, sizeof(ipHeader) + sizeof(tcpHeader));
//复制IP包+TCP包,进行发送
memcpy(SendBuf, &ipHeader, sizeof(ipHeader));
if ((sendto(sock, SendBuf, sizeof(ipHeader) + sizeof(tcpHeader), 0, (struct sockaddr *)&target, sizeof(struct sockaddr))) < 0)
{
cout << "sendto error" << endl << GetLastError() << endl;
}
int buflen = sizeof(target);
memset(RecvBuf, 0, sizeof(RecvBuf));
cout << "端口 " << port << endl;
shutdown(sock, 2);
closesocket(sock);
WSACleanup();
}
}
int main()
{
string ip = "10.15.57.1";
SynScan(ip, 1, 500);
system("pause");
return 0;
}