📄 scan_host.c.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 + -