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

📄 function.c

📁 unix下模仿ping功能
💻 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 + -