📄 function.c
字号:
#include "defs.h"
//-------------------------------------------------------------------------------------------------
/************ send_ping() function *********************
* Compose ICMP, The IP header will be prepended
* by the kernel.
*********************************************************/
void send_ping()
{
register int i;
register int j=0;
register struct icmp *icp; /* ICMP header */
register u_char *uptr; /* start of user data */
int rept_num=5; /*设置发送次数*/
int loop_num;
//struct timeval delay;
struct timespec delay;
struct timeval time_out;
while(ntransmitted<npackets)
{
/*设置发送时间间隔*/
delay.tv_sec = 0;
delay.tv_nsec =25000000; /*纳秒*/
icp = (struct icmp *)sendpack; /* pointer to ICMP header */
icp->icmp_type = ICMP_ECHO;
icp->icmp_code = 0;
icp->icmp_cksum = 0;
icp->icmp_id = ident; /* pid, to identify on return */
icp->icmp_seq = ntransmitted++; /* sequence number */
/* Add the time stamp of when we sent it */
if(timing)
{
gettimeofday((struct timeval *)&sendpack[SIZE_ICMP_HDR], (struct timezone *)0);
}
/* fill in the remainder of the packet with the user data. */
uptr = &sendpack[SIZE_ICMP_HDR + SIZE_TIME_DATA];
for(i = SIZE_TIME_DATA; i < datalen; i++)
*uptr++ = i;
/* Compute and store the ICMP checksum */
icp->icmp_cksum = in_cksum((u_short *)icp, packsize);
/* now send the datagram */
i = sendto(sockfd, sendpack, packsize, 0, (struct sockaddr *)&dest, sizeof(dest));
if(i < 0 || i != packsize)
{
if(i < 0)
{
fprintf(stderr, "sendto err\n");
sig_finish();
}
else
{
printf("test wrote %s %d bytes, return=%d\n", hostname, packsize, i);
}
}
//printf("send_ping-----npackets=%d,ntransmitted=%d\n",npackets,ntransmitted);
pthread_delay_np(&delay);
}
// add by lijinsong
delay.tv_nsec =20000000;/*20毫秒*/
int jj=0;
for (jj=0;jj<100;jj++)
{
pthread_delay_np(&delay);
}
//printf("send Time is over\n");
sig_finish();
//add by lijinsong
}
//------------------------------------------------------------------------------------------------
/***************** recv_ping() *************************
* Infinite loop to receive every ICMP packet received
* on the socket
*****************************************************/
void recv_ping()
{
register int n;
int fromlen;
struct sockaddr_in from;
while(nreceived<npackets)
{
fromlen = sizeof(from);
if((n = recvfrom(sockfd, recvpack, sizeof(recvpack), 0,(struct sockaddr *)&from, &fromlen)) < 0)
{
if(errno == EINTR)
{
continue;
}
fprintf(stderr, "recvfrom error\n");
continue;
}
pr_pack(recvpack, n, &from);
/**************************************************
* If we are only supposed to receive a certain
* number of packets, and we have reached the
* limit, stop
**************************************************/
//printf("recv_ping==npackets===[%d] ntransmitted=[%d] nreceived=[%d]\n",npackets,ntransmitted,nreceived);
/*收包间隔时间*/
}
sig_finish();
}
//------------------------------------------------------------------------------------------------
/************ pr_pack() function **************************
* to examine every received message. Print out the
* packet, if it came from us. The received msg includes
* iP header at the front * of the buffer.
******************************************************/
void pr_pack(char *buf, int cc, struct sockaddr_in *from)
{
int i, iphdrlen, triptime;
struct ip *ip; /* ptr to IP header */
register struct icmp *icp; /* ptr to ICMP header */
long *lp;
struct timeval tv;
u_long myi;
struct in_addr myaddr;
from->sin_addr.s_addr = ntohl(from->sin_addr.s_addr);/*将32位网络字符顺序转换成主机字符顺序*/
if(timing)
{
gettimeofday(&tv, (struct timezone *)0);
}
/***********************************************
* look at the IP header, to get its length.
* Verify that what follows the IP header
* contains at least an ICMP header (8 bytes min)
************************************************/
ip = (struct ip *)buf;
iphdrlen = ip->ip_hl << 2; /* 5x32bits word = 20 bytes */
if(cc < iphdrlen + ICMP_MINLEN) /*ICMP_MINLEN=8*/
{
if(verbose)
{
printf("packet too short (%d bytes) from %s\n", cc,
inet_ntoa(from->sin_addr));
return;
}
}
cc -= iphdrlen;
icp = (struct icmp *)(buf + iphdrlen); /* understand ! */
if(icp->icmp_type != ICMP_ECHOREPLY)
{/* It is not an ECHO replay */
if(verbose)
{
lp = (long *)buf;
myi = ntohl(from->sin_addr.s_addr);
myaddr.s_addr = myi;
printf("%d bytes from test1 %s: ", cc, inet_ntoa(myaddr));
}
return;
}
/* See if we sent the packet, and if not, just ignore it */
if(icp->icmp_id != ident)
return ;
myi = ntohl(from->sin_addr.s_addr);
myaddr.s_addr = myi;
//printf("%d bytes from test2 %s: ", cc, inet_ntoa(myaddr));
//printf("icmp_seq=%d ", icp->icmp_seq);
if(timing)
{
tvsub(&tv, (struct timeval *)&icp->icmp_data[0]);
triptime = tv.tv_sec * 1000 + (float)(tv.tv_usec/1000);
//printf("time=%d ms", triptime);
/*
triptime = tv.tv_sec * 1000000 + tv.tv_usec;
printf("time=%d us", triptime);
*/
tsum += triptime;
if(triptime < tmin)
tmin = triptime;
if(triptime > tmax)
tmax = triptime;
}
//putchar('\n');
/* only count echo replay packets that we sent */
nreceived++;
}
//---------------------------------------------------------------------------------------------
/*****************************************************
* tvsub
* Substract timeval structs: out = out - in
*****************************************************/
void tvsub(register struct timeval *out, register struct timeval *in)
{
if((out->tv_usec -= in->tv_usec) < 0) /* subtract microsec */
{
out->tv_sec--;
out->tv_usec += 1000000;
}
out->tv_sec -= in->tv_sec; /* subtract seconds */
}
//---------------------------------------------------------------------------------------------
/***************************************************
* Print out statistics and stop
***************************************************/
void sig_finish()
{
//printf("\n------%s PING Statistics----\n", hostname);
printf("Send %d Total packets, ", npackets);
printf("%d packets transmitted, ", ntransmitted);
printf("%d packets received, ", nreceived);
if(ntransmitted)
printf("%d%% packet loss",
(int)(((ntransmitted-nreceived)*100)/npackets));
printf("\n");
if(nreceived && timing)
{
//printf("round-trip (us) min/avg/max = %d/%.2f/%d\n",tmin, (float)tsum/nreceived, tmax);
printf("round-trip (ms) avg/max = %.2f/%d\n", (float)tsum/nreceived, tmax);
}
fflush(stdout);
exit(0);
}
//---------------------------------------------------------------------------------------------
/***************************************************
* Checksum routing for IP protocol family headers
*****************************************************/
u_short in_cksum(register u_short *ptr, register int nbytes)
{
register long sum;
u_short oddbyte;
register u_short answer;
sum = 0;
while(nbytes > 1)
{
sum += *ptr++;
nbytes -= 2;
}
if(nbytes == 1)
{
oddbyte = 0;
*((u_char *) &oddbyte) = *(u_char *)ptr;
sum += oddbyte;
}
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
answer = ~sum;
return answer;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -