📄 myping.cpp
字号:
//author: 10203201 张锟
#include<stdio.h>
#include<windows.h>
#include<process.h>
#pragma comment(lib,"ws2_32.lib")
#define SEND_SIZE 32
#define PACKET_SIZE 4096
//echo
#define ICMP_ECHO 8
#define ICMP_ECHOREPLY 0
//timestamp request
#define ICMP_TSTAMP 13
#define ICMP_TSTAMPREPLY 14
//mask request
#define ICMP_MASKREQ 17
#define ICMP_MASKREPLY 18
struct icmp
{
unsigned char icmp_type;
unsigned char icmp_code;
unsigned short icmp_cksum;
unsigned short icmp_id;
unsigned short icmp_seq;
union
{
struct timestamp
{
unsigned long or_time;
unsigned long re_time;
unsigned long tr_time;
} t_stamp;
unsigned long submask;
unsigned long data;
} icmp_option;
};
struct ip
{
unsigned char ip_hl:4;
unsigned char ip_v:4;
unsigned char ip_tos;
unsigned short ip_len;
unsigned short ip_id;
unsigned short ip_off;
unsigned char ip_ttl;
unsigned char ip_p;
unsigned short ip_sum;
unsigned long ip_src;
unsigned long ip_dst;
};
unsigned char sendpacket[PACKET_SIZE];
unsigned char recvpacket[PACKET_SIZE];
struct sockaddr_in dest_addr;
struct sockaddr_in sour_addr;
int sockfd;
int pid;
int icmp_type;
unsigned long icmp_sendtime;
unsigned short cal_chksum(unsigned short *addr,int len);
int pack(int pack_no);
int unpack(unsigned char *buf,int len);
void send_packet(void);
void recv_packet(void);
void main(int argc,char *argv[])
{
hostent *host;
WSADATA wsaData;
int timeout = 1000;
int SEND_COUNT = 4;
int i;
char *des_host;
des_host = argv[argc-1];
icmp_type = ICMP_ECHO;
switch(argc)
{
case 2:
break;
case 3:
if(strcmp(argv[1],"-t") == 0)
{
SEND_COUNT=10000;
break;
}
else if(strcmp(argv[1],"-m") == 0)
{
icmp_type = ICMP_MASKREQ;
break;
}
else if(strcmp(argv[1],"-s") == 0)
{
icmp_type = ICMP_TSTAMP;
break;
}
default:
printf("usage: %s [-t] [-m] [-s] Host name or IP address\n",argv[0]);
printf(" -t: ping until stopped\n -m: request for subnet mask\n -s: request for timestamp\n");
exit(1);
}
if(WSAStartup(0x1010,&wsaData)!=0)
{
printf("wsastartup error\n");
exit(1);
}
if((sockfd = socket(AF_INET,SOCK_RAW,IPPROTO_ICMP)) < 0)
{
printf("socket error\n");
exit(1);
}
if(setsockopt(sockfd,SOL_SOCKET,SO_RCVTIMEO,(char*)&timeout,sizeof(timeout))<0)
fprintf(stderr,"failed to set recv timeout: %d\n",WSAGetLastError());
if(setsockopt(sockfd,SOL_SOCKET,SO_SNDTIMEO,(char*)&timeout,sizeof(timeout))<0)
fprintf(stderr,"failed to set send timeout: %d\n",WSAGetLastError());
memset(&dest_addr,0,sizeof(dest_addr));
dest_addr.sin_family = AF_INET;
if(host = gethostbyname(des_host))
{
memcpy( (char *)&dest_addr.sin_addr,host->h_addr,host->h_length);
if(host = gethostbyaddr(host->h_addr,4,PF_INET))
des_host = host->h_name;
}
else if((dest_addr.sin_addr.s_addr = inet_addr(des_host)) == INADDR_NONE)
{
printf("Unkown host %s\n",des_host);
exit(1);
}
pid = getpid();
printf("Pinging %s [%s]: with %d bytes of data:\n\n",des_host,inet_ntoa(dest_addr.sin_addr),SEND_SIZE);
for(i=0;i<SEND_COUNT;i++)
{
send_packet();
recv_packet();
if(i != SEND_COUNT-1)
Sleep(1000);
}
}
//this algorithm is referenced from other's
unsigned short cal_chksum(unsigned short *addr,int len)
{
int nleft=len;
int sum=0;
unsigned short *w=addr;
unsigned short answer=0;
while(nleft>1)
{
sum+=*w++;
nleft-=2;
}
if( nleft==1)
{
*(unsigned char *)(&answer)=*(unsigned char *)w;
sum+=answer;
}
sum=(sum>>16)+(sum&0xffff);
sum+=(sum>>16);
answer=~sum;
return answer;
}
//pack
int pack(int pack_no)
{
int packsize;
struct icmp *icmp;
switch(icmp_type)
{
case ICMP_ECHO:
packsize = 8 + SEND_SIZE;
break;
case ICMP_TSTAMP:
packsize = 20;
break;
case ICMP_MASKREQ:
packsize = 12;
break;
default:
break;
}
icmp = (struct icmp*)sendpacket;
icmp->icmp_type = icmp_type;
icmp->icmp_code = 0;
icmp->icmp_cksum = 0;
icmp->icmp_seq = pack_no;
icmp->icmp_id = pid;
if(icmp_type == ICMP_TSTAMP)
{
icmp->icmp_option.t_stamp.or_time = GetTickCount();
icmp->icmp_option.t_stamp.re_time = 0;
icmp->icmp_option.t_stamp.tr_time = 0;
}
else if(icmp_type == ICMP_MASKREQ)
icmp->icmp_option.submask = 0;
else if(icmp_type == ICMP_ECHO)
memcpy(&icmp->icmp_option.data,"宁静致远淡泊明志——湖北襄樊张锟",sizeof("宁静致远淡泊明志——湖北襄樊张锟"));
icmp_sendtime = (unsigned long)GetTickCount();
icmp->icmp_cksum = cal_chksum((unsigned short *)icmp,packsize); /*check sum*/
return packsize;
}
//unpack
int unpack(unsigned char *buf,int len)
{
struct ip *ip;
struct icmp *icmp;
double rtt;
int iphdrlen;
int icmphdrlen;
ip = (struct ip *)buf;
iphdrlen = ip->ip_hl * 4;
switch(icmp_type)
{
case ICMP_ECHOREPLY:
icmphdrlen = 8;
case ICMP_TSTAMPREPLY:
icmphdrlen = 20;
case ICMP_MASKREPLY:
icmphdrlen = 12;
}
icmp = (struct icmp *)(buf + iphdrlen);
if(icmp->icmp_id == pid)
{
len = len - 20 - 8;
rtt = GetTickCount() - icmp_sendtime;
printf("Reply from %s: bytes=%d time=%.0fms TTL=%d icmp_seq=%u\n",inet_ntoa(sour_addr.sin_addr),len,rtt,ip->ip_ttl,icmp->icmp_seq);
switch(icmp->icmp_type)
{
case ICMP_ECHOREPLY:
break;
case ICMP_MASKREPLY:
printf("\tsubnet mask:%s\n",icmp->icmp_option.submask);
break;
case ICMP_TSTAMPREPLY:
printf("\toriginate timestamp: \t%d ms\n\treceive timestamp: \t%d ms\n\ttransmit timestamp: \t%d ms\n",icmp->icmp_option.t_stamp.or_time,icmp->icmp_option.t_stamp.re_time,icmp->icmp_option.t_stamp.tr_time);
break;
default:
break;
}
return 1;
}
return 0;
}
//send
void send_packet()
{
int packetsize;
static int pack_no=0;
packetsize = pack(pack_no++);
if(sendto(sockfd,(char *)sendpacket,packetsize,0,(struct sockaddr *)&dest_addr,sizeof(dest_addr)) < 0)
printf("Destination host unreachable.\n");
}
//receive
void recv_packet()
{
int n,fromlen;
int success;
fromlen = sizeof(sour_addr);
do
{
if((n = recvfrom(sockfd,(char *)recvpacket,64,0,(struct sockaddr *)&sour_addr,&fromlen)) >= 0)
success = unpack(recvpacket,n);
else if (WSAGetLastError() == WSAETIMEDOUT)
{
printf("Request timed out.\n");
return;
}
}while(!success);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -