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

📄 scanhost.cpp

📁 发现网络中的活动主机
💻 CPP
字号:
#pragma pack(4)
#pragma comment(lib,"WS2_32.LIB")
#define WIN32_LEAN_AND_MEAN
#include<winsock2.h>
#include<stdio.h>
#include<winsock.h>
#include<iostream.h>
#include<sys/timeb.h>
#include<time.h>
#include<winbase.h>
//头文件

typedef struct iphdr{                  //IP头
	unsigned int headlen:4;            //IP头长度
	unsigned int version:4;            //IP版本号
	unsigned char tos;                 //服务类型
	unsigned short id;                 //ID号
	unsigned short flag;               //标记
	unsigned char ttl;                 //生存时间
	unsigned char prot;                //协议
	unsigned short checksum;           //效验和
	unsigned int sourceIP;             //源IP
	unsigned int destIP;               //目的IP
}IpHeader;
//IP头部

typedef struct icmphdr{                //ICMP头
	BYTE type;                         //ICMP类型码
	BYTE code;                         //子类型码
	USHORT checksum;                   //效验和
    USHORT id;                         //ID号
	USHORT seq;                        //ICMP数据报的序列号
}IcmpHeader;
//ICMP包头部

#define ICMP_ECHO 8                    //请求回送
#define ICMP_ECHO_REPLY 0              //请求回应
#define ICMP_MIN 8                     //ICMP包头长度(最小ICMP包长度)
#define STATUS_FAILED 0xFFFF           //错误码
#define DEF_PACKET_SIZE 32             //缺省数据块长度
#define MAX_PACKET 1024                //最大数据块长度
#define MAX_PING_PACKET_SIZE (MAX_PACKET+sizeof(IpHeader))
//最大接收数据包长度

void fill_icmp_data(char *,int);
USHORT checksum(USHORT *,int);
void decode_resp(char *,int,struct sockaddr_in *);
DWORD WINAPI FindIP(LPVOID pIPAddrTemp);
//函数的申明

WSADATA wsaData;
SOCKET sockRaw;             //原始套接字
struct sockaddr_in dest,from,end;
//dest:搜索目的IP,
//from:接收ICMP包的源IP
//end:搜索终止IP。

int fromlen=sizeof(from);                      //接收ICMP包长度
char *recvbuf=new char[MAX_PING_PACKET_SIZE];  //接受ICMP包缓冲区
unsigned int addr=0;                           //IP地址
long ThreadNumCounter=0,ThreadNumLimit=20;     //线程数及最大允许线程数
long *aa=&ThreadNumCounter;
//全局变量的申明

void main(int argc,char *argv[])
{
	if(argc!=3)                               //判断格式是否正确
	{
		cout<<"输入格式错误:scanhost start_ip end_ip"<<endl;
		return;
	}
	if(WSAStartup(MAKEWORD(2,1),&wsaData)!=0)
	{
		cout<<"WSAStartup failed:"<<GetLastError()<<endl;
		ExitProcess(STATUS_FAILED);
	}
//创建原始套接字
	sockRaw=WSASocket(AF_INET,SOCK_RAW,IPPROTO_ICMP,NULL,0,WSA_FLAG_OVERLAPPED);
	if (sockRaw==INVALID_SOCKET)
	{
		cout<<"WSASocket() failed:"<<WSAGetLastError()<<endl;
		ExitProcess(STATUS_FAILED);
	}
	int timeout=1000;
	int bread=setsockopt(sockRaw,SOL_SOCKET,SO_RCVTIMEO,(char*)&timeout,sizeof(timeout));
	if(bread==SOCKET_ERROR)
	{
		cout<<"failed to set recv timeou:"<<WSAGetLastError()<<endl;
		ExitProcess(STATUS_FAILED);
	}
	timeout=1000;
	bread=setsockopt(sockRaw,SOL_SOCKET,SO_SNDTIMEO,(char*)&timeout,sizeof(timeout));
	if(bread==SOCKET_ERROR)
	{
		cout<<"failed to set send timeout:"<<WSAGetLastError()<<endl;
		ExitProcess(STATUS_FAILED);
	}
	memset(&dest,0,sizeof(dest)); //初始化dest结构
	unsigned long startIP,endIP;  
	dest.sin_family=AF_INET;
	dest.sin_addr.s_addr=inet_addr(argv[1]);  //填入开始搜索IP
	startIP=inet_addr(argv[1]);
	end.sin_family=AF_INET;
	end.sin_addr.s_addr=inet_addr(argv[2]);
	endIP=inet_addr(argv[2]);    //填入结束搜索IP地址
	HANDLE hThread;
	while(htonl(startIP)<=htonl(endIP))   //起始IP比结束IP小
	{
		if(ThreadNumCounter>ThreadNumLimit) //判断线程数目,如果太多,休眠
		{
			Sleep(5000);
			continue;
		}
		DWORD ThreadID;
		sockaddr_in * pIPAddrTemp=new(sockaddr_in);
		if(!pIPAddrTemp)
		{
			cout<<"memory alloc failed"<<endl;
			return;
		}
		*pIPAddrTemp=dest;
		clock_t start;
		start=clock();
		hThread=CreateThread(NULL,NULL,FindIP,(LPVOID)pIPAddrTemp,NULL,&ThreadID);
		long i=60000000L;
		while(i--);
		TerminateThread(hThread,0);
		InterlockedDecrement(aa);
		memset(&from,0,sizeof(from));
		startIP=htonl(htonl(startIP)+1);
		dest.sin_addr.s_addr=startIP;
	}
	while(ThreadNumCounter!=0)
	{
		Sleep(2000);
		return;
	}
}

void fill_icmp_data(char *icmp_data,int datasize)
{
	IcmpHeader *icmp_hdr;
	char *datapart;
	icmp_hdr=(IcmpHeader*)icmp_data;
	icmp_hdr->type=ICMP_ECHO;//设置类型信息
	icmp_hdr->id=(USHORT)GetCurrentThreadId();//设置其ID号为当前线程ID号
	datapart=icmp_data+sizeof(IcmpHeader);//计算ICMP数据报的数据部分
	memset(datapart,'A',datasize-sizeof(IcmpHeader));//填入数据
}
//ICMP数据包的填充

void decode_resp(char *buf,int bytes,struct sockaddr_in *from)
{
	IpHeader *iphdr;
	IcmpHeader *icmphdr;
	unsigned short iphdrlen;
	iphdr=(IpHeader *)buf;
	iphdrlen=iphdr->headlen*4;
	icmphdr=(IcmpHeader *)(buf+iphdrlen);

	if(bytes<iphdrlen+ICMP_MIN)return;
	if(icmphdr->type!=ICMP_ECHO_REPLY)return;
	if(icmphdr->id!=(USHORT)GetCurrentThreadId())return;
	cout<<"活动主机:"<<inet_ntoa(from->sin_addr)<<endl;
}
//返回包的解析,以及输出

USHORT 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);
}
//效验和的计算

DWORD WINAPI FindIP(LPVOID pIPAddrTemp)
{
	InterlockedIncrement(aa);//线程数目+1
	char icmp_data[MAX_PACKET];
	memset(icmp_data,0,MAX_PACKET);//数据报初始化
	int datasize=DEF_PACKET_SIZE;//数据报报文的缺省长度
	datasize+=sizeof(IcmpHeader);//加上icmp头部长度
	fill_icmp_data(icmp_data,datasize);//填充包
	((IcmpHeader*)icmp_data)->checksum=0;//效验和置零
	((IcmpHeader*)icmp_data)->seq=0;//序列号置零
	((IcmpHeader*)icmp_data)->checksum=checksum((USHORT*)icmp_data,datasize);
	//计算效验和后填人
	int bwrote=sendto(sockRaw,icmp_data,datasize,0,(struct sockaddr*)pIPAddrTemp,sizeof(dest));
	//发送数据报
	int n=0;
	if(bwrote==SOCKET_ERROR)
	{
		if(WSAGetLastError()==WSAETIMEDOUT)
		{
			cout<<"timed out"<<endl;
		}
		cout<<"sendto failed:"<<WSAGetLastError()<<endl;
		ExitProcess(STATUS_FAILED);
		n=1;
	}
	if (WSAGetLastError()==WSAETIMEDOUT)
	{
		cout<<"timed out"<<endl;
		ExitProcess(STATUS_FAILED);
		n=1;
	}
	if(bwrote<datasize)
	{
		cout<<"Wrote"<<bwrote<<"bytes"<<endl;
		ExitProcess(STATUS_FAILED);
		n=1;
	}
	int bread=recvfrom(sockRaw,recvbuf,MAX_PING_PACKET_SIZE,0,(struct sockaddr*)&from,&fromlen);
	//数据包的接收
	if(bread==SOCKET_ERROR)
	{
		if (WSAGetLastError()==WSAETIMEDOUT)
		{
			cout<<"timed out"<<endl;
		}
		cout<<"recvfrom failed:"<<WSAGetLastError()<<endl;
		ExitProcess(STATUS_FAILED);
		n=1;
	}
	if(n==0)
		decode_resp(recvbuf,bread,&from);
	InterlockedDecrement(aa);
	return 0;
}
//子线程的编写

⌨️ 快捷键说明

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