A piece of C program code on the internet, hoping to be useful to you
# Include <stdio. h>
# Include <signal. h>
# Include <ARPA/inet. h>
# Include <sys/types. h>
# Include <sys/socket. h>
# Include <unistd. h>
# Include <netinet/in. h>
# Include <netinet/IP. h>
# Include <netinet/ip_icmp.h>
# Include <netdb. h>
# Include <setjmp. h>
# Include <errno. h>
# Define packet_size 4096
# Define max_wait_time 5
# Define max_no_packets 3
Char sendpacket [packet_size];
Char recvpacket [packet_size];
Int sockfd, datalen = 56;
Int nsend = 0, nsent ED = 0;
Struct sockaddr_in dest_addr;
Pid_t PID;
Struct sockaddr_in from;
Struct timeval tvrecv;
Void statistics (INT signo );
Unsigned short cal_chksum (unsigned short * ADDR, int Len );
Int pack (INT pack_no );
Void send_packet (void );
Void recv_packet (void );
Int unpack (char * Buf, int Len );
Void TV _sub (struct timeval * Out, struct timeval * In );
Void statistics (INT signo)
{Printf ("/n -------------------- Ping statistics -------------------/N ");
Printf ("% d packets transmitted, % d received, % d lost/N", nsend, nreceived,
(Nsend-nreceived)/nsend * 100 );
Close (sockfd );
Exit (1 );
}
/* Checksum algorithm */
Unsigned short cal_chksum (unsigned short * ADDR, int Len)
{Int nleft = Len;
Int sum = 0;
Unsigned short * w = ADDR;
Unsigned short answer = 0;
/* Accumulate the ICMP header binary data in 2 bytes */
While (nleft> 1)
{Sum + = * w ++;
Nleft-= 2;
}
/* If the ICMP header is an odd number of bytes, the last byte is left. The last byte is regarded as a high byte of 2 bytes of data. The low byte of the 2 bytes of data is 0 and continues to accumulate */
If (nleft = 1)
{* (Unsigned char *) (& answer) = * (unsigned char *) W;
Sum + = answer;
}
Sum = (sum> 16) + (sum & 0 xFFFF );
Sum + = (sum> 16 );
Answer = ~ SUM;
Return answer;
}
/* Set the ICMP header */
Int pack (INT pack_no)
{Int I, packsize;
Struct ICMP * ICMP;
Struct timeval * tval;
ICMP = (struct ICMP *) sendpacket;
ICMP-> icmp_type = ICMP_Echo;
ICMP-> icmp_code = 0;
ICMP-> icmp_cksum = 0;
ICMP-> icmp_seq = pack_no;
ICMP-> icmp_id = PID;
Packsize = 8 + datalen;
Tval = (struct timeval *) ICMP-> icmp_data;
Gettimeofday (tval, null);/* record sending time */
ICMP-> icmp_cksum = cal_chksum (unsigned short *) ICMP, packsize);/* validation algorithm */
Return packsize;
}
/* Send three ICMP packets */
Void send_packet ()
{Int packetsize;
While (nsend <max_no_packets)
{Nsend ++;
Packetsize = pack (nsend);/* Set ICMP header */
If (sendto (sockfd, sendpacket, packetsize, 0,
(Struct sockaddr *) & dest_addr, sizeof (dest_addr) <0)
{Perror ("sendto error ");
Continue;
}
Sleep (1);/* Send an ICMP packet every second */
}
}
/* Receive all ICMP packets */
Void recv_packet ()
{Int N, fromlen;
Extern int errno;
Signal (sigalrm, statistics );
Fromlen = sizeof (from );
While (nreceived <nsend)
{ALARM (max_wait_time );
If (n = recvfrom (sockfd, recvpacket, sizeof (recvpacket), 0,
(Struct sockaddr *) & from, & fromlen) <0)
{If (errno = eintr) continue;
Perror ("recvfrom error ");
Continue;
}
Gettimeofday (& tvrecv, null);/* record receipt time */
If (unpack (recvpacket, n) =-1) continue;
Nreceived ++;
}
}
/* Strip the ICMP header */
Int unpack (char * Buf, int Len)
{Int I, iphdrlen;
Struct IP * IP;
Struct ICMP * ICMP;
Struct timeval * tvsend;
Double RTT;
IP = (struct IP *) BUF;
Iphdrlen = IP-> ip_hl <2;/* calculate the length of the IP header, that is, the length mark of the IP header multiplied by 4 */
ICMP = (struct ICMP *) (BUF + iphdrlen);/* cross the IP header and point to the ICMP header */
Len-= iphdrlen;/* total length of the ICMP header and ICMP datagram */
If (LEN <8)/* It is unreasonable if it is smaller than the ICMP header length */
{Printf ("ICMP packets/'s length is less than 8/N ");
Return-1;
}
/* Make sure that the ICMP response I sent is received */
If (ICMP-> icmp_type = ICMP_ECHOREPLY) & (ICMP-> icmp_id = PID ))
{Tvsend = (struct timeval *) ICMP-> icmp_data;
TV _sub (& tvrecv, tvsend);/* time difference between receiving and sending */
RTT = tvrecv. TV _sec * 1000 + tvrecv. TV _usec/1000;/* calculate RTT in milliseconds */
/* Display related information */
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;
}
Main (INT argc, char * argv [])
{Struct hostent * Host;
Struct protoent * protocol;
Unsigned long inaddr = 0l;
Int waittime = max_wait_time;
Int size = 50*1024;
If (argc <2)
{Printf ("Usage: % s Hostname/IP Address/N", argv [0]);
Exit (1 );
}
If (Protocol = getprotobyname ("ICMP") = NULL)
{Perror ("getprotobyname ");
Exit (1 );
}
/* Generate the original socket that uses ICMP. This socket can be generated only by root */
If (sockfd = socket (af_inet, sock_raw, protocol-> p_proto) <0)
{Perror ("socket error ");
Exit (1 );
}
/* Revoke the root permission and set the current user permission */
Setuid (getuid ());
/* Expand the socket receiving buffer to 50 K to reduce the overflow of the receiving buffer.
If you accidentally ping a broadcast address or multicast address, a large number of responses will be received */
Setsockopt (sockfd, sol_socket, so_rcvbuf, & size, sizeof (size ));
Bzero (& dest_addr, sizeof (dest_addr ));
Dest_addr.sin_family = af_inet;
/* Identify the host name or IP address */
If (inaddr = inet_addr (argv [1]) = inaddr_none)
{If (host = gethostbyname (argv [1]) = NULL)/* is the host name */
{Perror ("gethostbyname error ");
Exit (1 );
}
Memcpy (char *) & dest_addr.sin_addr, host-> h_addr, host-> h_length );
}
Else/* is an IP address */
Memcpy (char *) & dest_addr, (char *) & inaddr, host-> h_length );
/* Obtain the main process ID, which is used to set the ICMP flag */
PID = getpid ();
Printf ("Ping % s (% s): % d bytes data in ICMP packets./N", argv [1],
Inet_ntoa (dest_addr.sin_addr), datalen );
Send_packet ();/* Send all ICMP packets */
Recv_packet ();/* receive all ICMP packets */
Statistics (sigalrm);/* for Statistics */
Return 0;
}
/* Subtract two timeval structures */
Void TV _sub (struct timeval * Out, struct timeval * in)
{If (out-> TV _usec-= In-> TV _usec) <0)
{-- Out-> TV _sec;
Out-> TV _usec + = 1000000;
}
Out-> TV _sec-= In-> TV _sec;
}
/* ------------- The end -----------*/