📄 ping.cpp
字号:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/types.h>
#include <netinet/ip_icmp.h>
#define WAIT_TIME 3
#define BUFFER_SIZE 1024
//ICMP报头解析代码
int unpack_packet_header(char * buf,int len,struct sockaddr_in *from)
{
int i,iphdrlen;
struct ip*ip;
struct icmp* icmp;
struct timeval *tvsend;
struct timeval tvrecv;
double rtt;
ip=(struct ip*)buf;
iphdrlen=ip->ip_hl*4;
icmp=(struct icmp *)(buf+iphdrlen);
len-=iphdrlen;
if(len<8)
{
printf("ICMP packets\' s length is less than 8\n");
return -1;
}
if(icmp->icmp_type==ICMP_ECHOREPLY)
{
tvsend=(struct timeval *)icmp->icmp_data;
gettimeofday(&tvrecv,NULL);
if((tvrecv.tv_usec-=tvsend->tv_usec)<0)
{
tvrecv.tv_sec--;
tvrecv.tv_usec+=1000000;
}
tvrecv.tv_sec-=tvsend->tv_sec;
rtt=tvrecv.tv_sec *1000+tvrecv.tv_usec/1000;
printf("%d byte from %s: icmp_seq=%u ttl=%d rtt=%.3f ms\n",
len,
inet_ntoa(from->sin_addr),
icmp->icmp_seq,
ip->ip_ttl,
rtt);
}
else
return -1;
}
u_short cal_cksum(const u_short *addr,register int len, u_short csum)
{
register int nleft=len;
const u_short *w=addr;
register u_short answer;
register int sum=csum;
while(nleft>1)
{
sum+=*w++;
nleft-=2;
}
if(nleft==1)
sum+=htons(*(u_char *)w<<8);
sum=(sum>>16)+(sum & 0xffff);
sum+=(sum>>16);
answer=~sum;
return (answer);
}
int main(int argc,char *argv[])
{
int sock;
struct sockaddr_in sin;
unsigned short local_port;
unsigned char protocol;
char * buffer,*buffer2,*dnsdata;
struct iphdr *ip_header;
struct icmphdr *icmp_header;
char *remote_ip_str;
unsigned short buffer_size,buffer_size2;
int tmp,len;
short randomseq;
if(argc!=3)
{
printf("two arguments \n");
return 0;
}
protocol=IPPROTO_ICMP;
local_port=atoi(argv[1]);
remote_ip_str=argv[2];
sock=socket(PF_INET,SOCK_RAW,protocol);
if(sock<0)
{
printf("create socket error\n");
return 0;
}
memset(&sin,0,sizeof(sin));
sin.sin_port=htons(local_port);
if(bind(sock,(struct sockaddr *)&sin,sizeof(sin))<0)
{
printf("bind error\n");
return 0;
}
tmp=1;
setsockopt(sock,0,IP_HDRINCL,&tmp,sizeof(tmp));
buffer_size=sizeof(struct iphdr)+sizeof(struct icmphdr)+sizeof(struct timeval);
buffer_size2=BUFFER_SIZE;
memset(buffer,0,sizeof(buffer));
memset(&sin,0,sizeof(sin));
sin.sin_family=AF_INET;
sin.sin_addr.s_addr=inet_addr(remote_ip_str);
ip_header=(struct iphdr *)buffer;
ip_header->ihl=5;
ip_header->version=4;
ip_header->tos=0;
ip_header->tot_len=htons(buffer_size);
ip_header->id=rand();
ip_header->ttl=64;
ip_header->frag_off=0x40;
ip_header->protocol=protocol;
ip_header->check=0;
ip_header->daddr=inet_addr(remote_ip_str);
ip_header->saddr=0;
icmp_header=(struct icmphdr *)(ip_header+1);
icmp_header->type=ICMP_ECHO;
icmp_header->code=0;
icmp_header->un.echo.id=htons(local_port);
icmp_header->un.echo.sequence=0;
struct timeval *tp=(struct timeval *)&buffer[28];
gettimeofday(tp,NULL);
icmp_header->checksum=cal_cksum((const u_short *) icmp_header,sizeof(struct icmphdr)
+sizeof(struct timeval),0);
if(sendto(sock,buffer,buffer_size,0,(struct sockaddr *)&sin,sizeof(struct sockaddr_in)) <0)
{
printf("send error\n");
return 0;
}
printf("send ICMP inquery\n");
len=sizeof(sin);
//不同之处//////////////////////////////////
alarm(WAIT_TIME);
////////////////////////////////////////
if(recvfrom(sock,buffer2,buffer_size2,0,(struct sockaddr *)&sin,&len)<0)
{
printf("receive error\n");
return 0;
}
printf("received Destionation response\n");
//显示报文信息
unpack_packet_header(buffer2,buffer_size2,(struct sockaddr_in *)&sin);
close(sock);
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -