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

📄 scan_host.c.bak

📁 linux下主机扫描程序的具体实现代码。具体一定的参考价值
💻 BAK
字号:
#include <stdio.h>
#include <unistd.h>
#include <sys/select.h>
#include <string.h>
#include <netinet/ip_icmp.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#define  PACK_LEN 72
#define   BUFSIZE  4096

//一个主机扫描程序

void tvsub(struct timeval* out,struct  timeval *in)
{
	out->tv_sec-=in->tv_sec;
}

u_short checksum(u_short *data,int len)
{
		u_long sum=0;
		for(;len>1;len-=2)
		{
				sum+=*data++;
				if(sum & 0x80000000)
						sum=(sum & 0xffff)+(sum>>16);
		}
		if(len==1)
		{
				u_short i=0;
				*(u_char*)(&i)=*(u_char*)data;
				sum+=i;
		}
		while(sum>>16)
		{
				sum=(sum & 0xffff)+(sum>>16);
		}
		return (sum==0xffff)?sum:~sum;

}


//功能生成ICMP包数据
void  make_icmp_packet(struct icmp *icmp,int len,int n)
{
	 memset((char *)icmp,0,len);
	  gettimeofday((struct timeval*)(icmp->icmp_data),(struct timezone*)0 );
	 //生成ICMP报头
	 icmp->icmp_type=ICMP_ECHO;
	 icmp->icmp_code=0;
	 icmp->icmp_id=getpid();
	 icmp->icmp_seq=n;
	 icmp->icmp_cksum=0;//进行检查和
	 icmp->icmp_cksum=checksum((u_short*)icmp,len);
}

int main(int argc, char *argv[])
{
	struct sockaddr_in send_sa;
	//struct s;
	int i=0,j=0;
	int scan_icmp_socket;
	char send_buff[PACK_LEN];
	char  recv_buff[BUFSIZE];
	struct in_addr  start_addr,end_addr;
	//uint32_t start_ip; //扫描IP的初始值
	//uint32_t   end_ip;
	//uint32_t   dst_ip;
	struct timeval tv;
	fd_set readfd_set;
	struct  ip  *ip;
	struct  icmp *icmp;
	int hlen;     //报头 长度

	send_sa.sin_family=AF_INET;
	scan_icmp_socket=socket(AF_INET,SOCK_RAW,IPPROTO_ICMP);
	if (scan_icmp_socket<0)
	{
			perror("scan_icmp_socket:");
			return -1;
	}
	char  ip_addr[17];
	//循环ip地址
    for (j=1;j<254;j++)
    {
		  memset(ip_addr,'\0',sizeof(ip_addr));
		  sprintf(ip_addr,"%s.%d",argv[1],j);
		  send_sa.sin_addr.s_addr=inet_addr(ip_addr);
		  printf("scan %s\n",inet_ntoa(send_sa.sin_addr));
		  fflush(stdout);
		  for (i=0;i<3 ;i++ )
		  {
				make_icmp_packet((struct icmp*)send_buff,PACK_LEN,i);
				if ( (sendto(scan_icmp_socket,send_buff,PACK_LEN,0,(struct sockaddr*)&send_sa,sizeof(send_sa)))<0 )
				{
					 perror("sendto");
				}
				//设定超时0.2妙
				tv.tv_sec=0;
				tv.tv_usec=200*1000;
				FD_ZERO(&readfd_set);
				FD_SET(scan_icmp_socket,&readfd_set);
				while(1)
			  {
					if (select(scan_icmp_socket+1,&readfd_set,NULL,NULL,&tv)<=0)
					{
						break;
					}
					//等待0.2妙后如果数据有回应那么就开始接收包含ICMP包的IP报
					if (recvfrom(scan_icmp_socket,recv_buff,BUFSIZE,0,NULL,NULL)<=0)
					{
					 perror("recvfrom:");
					 exit(0);
					}
					ip=(struct ip*)recv_buff;
					//获得IP数据包长度;
					hlen=ip->ip_hl<<2;
					//根据IP的源ip是否和自己相同判断是否是自己收到的包
					if (ip->ip_src.s_addr==send_sa.sin_addr.s_addr)
					{
						icmp=(struct icmp*)(recv_buff+hlen);
						//解析icmp包内容信息
						if (icmp->icmp_type==ICMP_ECHOREPLY)
						{
							printf("%-15s",inet_ntoa( *(struct in_addr*) &(ip->ip_src.s_addr)));
							//获得当前系统时间后与ICMP包内的数据内容对比
							gettimeofday(&tv,NULL);
							tvsub(&tv,(struct timeval*) (icmp->icmp_data));
							printf(":RTT=%8.4f  ms\n",tv.tv_sec+tv.tv_usec/1000.0);
							break;
						}
						else
						{
							 printf("ICMP STATE:%d\n",icmp->icmp_type);
						}
					}
			  }
		  }
		
    }
	close(scan_icmp_socket);
	return 0;
}

⌨️ 快捷键说明

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