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

📄 ping.c

📁 实现ping功能,返回ping的结果.可以直接调用此函数,通则返回true,不通则返回false.
💻 C
字号:
//*******************************************************************
// A ping program.
// Copright by Hugo. 2006/03/20
//*******************************************************************
#include <stdio.h>
#include <sys/types.h> 
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h> 
#include <netinet/in_systm.h>
#include <sys/select.h>
#include <sys/time.h>
#include <fcntl.h>
#include <errno.h>
#include <signal.h>
#include <arpa/inet.h>
#include <stdlib.h>
// IP Header -- RFC 791 
#define ICMP_ECHOREPLY 0
#define ICMP_ECHO 8
#define REQ_DATASIZE 32 
#define MAX_WAIT_TIME   500//ms
#define MAX_SEND   1
int nsend=0,nreceived=0;
int sockfd;
typedef struct tagIPHDR
{
u_char VIHL; // Version and IHL
u_char TOS; // Type Of Service
short TotLen; // Total Length
short ID; // Identification
short FlagOff; // Flags and Fragment Offset
u_char TTL; // Time To Live
u_char Protocol; // Protocol
u_short Checksum; // Checksum
struct in_addr iaSrc; // Internet Address - Source
struct in_addr iaDst; // Internet Address - Destination
}IPHDR, *PIPHDR;
// ICMP Header - RFC 792
typedef struct tagICMPHDR
{
u_char Type; // Type
u_char Code; // Code
u_short Checksum; // Checksum
u_short ID; // Identification
u_short Seq; // Sequence
char Data; // Data
}ICMPHDR, *PICMPHDR;
// ICMP Echo Request
typedef struct tagECHOREQUEST
{
ICMPHDR icmpHdr;
struct timeval echoTime;
char cData[REQ_DATASIZE];
}ECHOREQUEST, *PECHOREQUEST;
// ICMP Echo Reply
typedef struct tagECHOREPLY
{
IPHDR ipHdr;
ECHOREQUEST echoRequest;
char cFiller[256];
}ECHOREPLY, *PECHOREPLY;
pid_t pid;
void tv_sub(struct timeval *out,struct timeval *in);
unsigned short checksum(unsigned short *buffer, int size);
int WaitForEchoReply(int socket);
int statistics(int signo);

int main(int argc,char *argv[])
{
int result=0;
char ip[20];
 if(argc<2)
    {    
           printf("usage:%s hostname/IP address\n",argv[0]);
           exit(1);
    }
strcpy(ip,argv[1]);
result=ping(&result,ip);
if(result)
printf("ping success!\n");
else
	printf("ping fail!\n");
}

int ping(int * flag,char *ip) 
{ 
int send_times=MAX_SEND;

int nRet;
struct sockaddr_in addrDest;
struct hostent *Dest;
float spenttime;

if ((Dest=gethostbyname(ip)) == NULL)
{
/* get the host info */
herror("gethostbyname");
exit(1);
}
printf("Host name : %s\n", Dest->h_name);
// printf("IP Address : %s\n",inet_ntoa(*((struct in_addr *)Dest->h_addr)));
if((sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0)
{ 
perror("socket"); 
exit(1); 
} 
addrDest.sin_addr = *((struct in_addr *)Dest->h_addr);
addrDest.sin_family = AF_INET;
bzero(&(addrDest.sin_zero), 8); 
ECHOREQUEST echoReq;
echoReq.icmpHdr.Type = ICMP_ECHO;
echoReq.icmpHdr.Code = 0;
echoReq.icmpHdr.ID =getpid();
int Seq = 0;
for (nRet = 0; nRet < REQ_DATASIZE; nRet++)
echoReq.cData[nRet] = ' '+nRet;



 signal(SIGALRM,statistics);

 ualarm(MAX_WAIT_TIME*1000,0);
while(send_times--){
echoReq.icmpHdr.Seq = Seq++;
echoReq.icmpHdr.Checksum = 0;
gettimeofday(&echoReq.echoTime,NULL);
echoReq.icmpHdr.Checksum = checksum((unsigned short*)&echoReq, sizeof(struct tagECHOREQUEST));
if (sendto(sockfd, (struct ECHOREQUEST*)&echoReq, sizeof(struct tagECHOREQUEST), 0, (struct sockaddr *)&addrDest, sizeof(addrDest)) < 0)
{ 
perror("sendto");
exit(1);
}
else
   nsend++;

if(WaitForEchoReply(sockfd) == -1)
{
perror("select");
exit(1); 
}

ECHOREPLY icmpRecv;
int addr_len;
addr_len = sizeof(struct sockaddr);



if (recvfrom(sockfd, (struct ECHOREPLY*)&icmpRecv, sizeof(struct tagECHOREPLY), 0, (struct sockaddr *)&addrDest, &addr_len) < 0)
{ 
perror("sendto"); 
}
else if(icmpRecv.echoRequest.icmpHdr.Type == ICMP_ECHOREPLY)
{
nreceived++;
gettimeofday(&icmpRecv.echoRequest.echoTime, NULL);
tv_sub(&icmpRecv.echoRequest.echoTime, &echoReq.echoTime);
spenttime=icmpRecv.echoRequest.echoTime.tv_sec*1000+icmpRecv.echoRequest.echoTime.tv_usec*0.001;
printf("Reply from %s: Bytes=%d Id_seq = %d time=%4.3fms TTL=%d\n",Dest->h_name, sizeof(icmpRecv.echoRequest), icmpRecv.echoRequest.icmpHdr.Seq, spenttime,icmpRecv.ipHdr.TTL);
sleep(1);
}
else if(icmpRecv.echoRequest.icmpHdr.Type == ICMP_ECHO)
{
	printf("127.0.0.1\n");
	nsend--;
send_times++;
}
}
} 
unsigned short checksum(unsigned short *buffer, int size)
{
unsigned long cksum=0;
while(size >1)
{
cksum+=*buffer++;
size -=sizeof(unsigned short);
} 
if(size)
{
cksum += *(unsigned char*)buffer;
}
cksum = (cksum >> 16) + (cksum & 0xffff);
cksum += (cksum >>16);
return (unsigned short)(~cksum);
}
//Wait for echoRecv
int WaitForEchoReply(int socket)
{
int i;
struct timeval Timeout;
fd_set readfds;
FD_ZERO(&readfds);
FD_SET(socket, &readfds);
Timeout.tv_sec =0;
Timeout.tv_usec = 100000;

return(select(socket+1, &readfds, NULL, NULL, &Timeout));
}
/*timeval*/ 
void tv_sub(struct timeval *out,struct timeval *in) 
{
if( (out->tv_usec-=in->tv_usec)<0) 
{
--out->tv_sec; 
out->tv_usec+=500000; 
} 
out->tv_sec-=in->tv_sec; 
}
int statistics(int signo)
{  

/*
printf("nsend=%d\n",nsend);
printf("nreceived=%d\n",nreceived);
    printf("\n--------------------PING statistics-------------------\n");
    printf("%d packets transmitted, %d received , %%%d lost\n",nsend,nreceived,(nsend-nreceived)/nsend*100);
    close(sockfd);
	exit(0);*/
 close(sockfd);
	printf("nsend=%d\n",nsend);
printf("nreceived=%d\n",nreceived);

	printf("%d packets transmitted, %d received , %d%% lost\n",nsend,nreceived,(int)(((float)(nsend-nreceived))/((float)nsend)*100));
	if (nsend==nreceived)
    return 1;
	else
	  return 0;
}

⌨️ 快捷键说明

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