Attached Source: Ping.cpp Ping.h is the implementation of the class.
The instance code is stripped from the application of the project:
Ping.cpp:
#include "ping.h" ping::P ing () {m_maxpacketsize = 4;m_datalen = 56;m_nsend = 0;m_nreceived = 0;m_icmp_seq = 0;} /* Checksum algorithm */unsigned short ping::getchksum (Unsigned short *addr,int len) { int nleft=len;int sum=0;unsigned short *w=addr;unsigned short answer=0;/* Add the ICMP header binary data in 2-byte increments */while (nleft>1) { sum+=*w++;nleft-=2;} /* If the ICMP header is an odd number of bytes, the last byte is left. Consider the last byte as a high byte of 2 bytes of data, the low byte of this 2 byte data is 0, continue to accumulate */if ( nleft==1) { * (unsigned char *) ( &answer) =* (unsigned char *) w;sum+=answer;} Sum= (sum>>16) + (SUM&0XFFFF); sum+= (sum>>16); answer=~sum;return answer;} /* Set ICMP header */int ping::p ackicmp (int pack_no, struct icmp* icmp) { int i,packsize;struct icmp *picmp;struct timeval *tval;picmp = icmp;picmp-> Icmp_type=icmp_echo;picmp->icmp_code=0;picmp->icmp_cksum=0;picmp->icmp_seq=pack_no;picmp->icmp_id= m_pid;packsize= 8 + m_datalen;tval= (struct timeval *) icmp->icmp_data;gettimeofday (tval,null); /* Record Send Time */picmp->icmp_cksum=getchksum ((unsigned short *) icmp,packsize); /* Check algorithm */ Return packsize;} /* peel off the ICMP header */bool ping::unpackicmp (char *buf,int len, struct icmpechoreply * icmpechoreply) { int i,iphdrlen;struct ip *ip;struct icmp *icmp; struct timeval *tvsend, tvrecv, tvresult;double rtt;ip = (Struct ip *) buf;iphdrlen = ip->ip_hl << 2; /* IP header length, That is, the length of the IP header is marked by 4*/icmp = (struct icmp *) (Buf + iphdrlen); /* crosses the IP header, Point to ICMP header */len -= iphdrlen; /* The total length of the ICMP header and the ICMP datagramDegree */if (len < 8) /* less than the ICMP header length is unreasonable */{ printf ("Icmp packets\ ' s length is Less than 8\n "); return false;} /* Make sure to receive the ICMP response I sent */if ( (icmp->icmp_type==icmp_echoreply) && (icmp->icmp_id == m_pid) ) { tvsend= (struct timeval *) icmp->icmp_data; Gettimeofday (&tvrecv,null); /* record receive Time */tvresult = tvsub (tvrecv, *tvsend); /* The time difference */rtt=tvresult.tv_sec*1000 + tvresult.tv_usec/1000; /* received and sent is calculated in milliseconds rtt*/ icmpechoreply->rtt = rtt;icmpechoreply->icmpseq = icmp->icmp_seq;icmpechoreply- >ipttl = ip->ip_ttl;icmpechoreply->icmplen = len;return true;} Else {return false;}} /* Two timeval structure subtraction */struct timeval ping::tvsub (struct timeval timeval1,STRUCT&NBSP;TIMEVAL&NBSP;TIMEVAL2) { struct timeval result;result = timeval1;if (result.tv_usec < timeval2.tv_usec < 0) { --result.tv_ sec;result.tv_usec += 1000000;} Result.tv_sec -= timeval2.tv_sec;return result;} /* Send three ICMP messages */bool ping::sendpacket () { size_t packetsize;while ( m_nsend < m_maxpacketsize) { m_nsend++;m_icmp_seq++;p acketsize = packicmp (m_icmp_seq , (struct icmp*) m_sendpacket) /* set ICMP header */if (SendTo, 0, (struct sockaddr *) &m_dest_addr, sizeof (m_dest_addr)) < 0 ) { perror ("sendto error"); continue;}} Return true;} /* Receive all ICMP message */bool ping::recvpacket (Pingresult &pingresult) { int len;extern int errno;strUct icmpechoreply icmpechoreply;int maxfds = m_sockfd + 1;int nfd = 0;fd_set rset; fd_zero (&rset); Socklen_t fromlen = sizeof (M_FROM_ADDR); struct timeval timeout;timeout.tv_sec = 4;timeout.tv_usec = 0;for (int recvcount = 0; recvcount < m_maxpacketsize; recvcount++) { //printf ("begin recv\n"); Fd_set (M_sockfd, &rset);if (Nfd = select (maxfds, &rset, null, null , &timeout) == -1) { perror ("Select error");continue; }if (nfd == 0) {/ /recv time out //printf ("request timeout\n");icmpechoreply.isreply = false; PingResult.icmpEchoReplys.push_back (icmpechoreply); continue;} if (Fd_isset (M_sockfd, &rset)) {if ( (Len = recvfrom (M_sockfd, m_recvpacket, sizeof (M_recvpacket),0, (struct sockaddr *) &m_from_addr,&fromlen) <0) { if (ERRNO==EINTR) continue;perror ("Recvfrom error"); continue;} Icmpechoreply.fromaddr = inet_ntoa (M_FROM_ADDR.SIN_ADDR) ;if (icmpechoreply.fromaddr !=&NBSP;PINGRESULT.IP) {//printf ("invalid address, discard\n");//retry againrecvcount--; Continue;}} if (unpackicmp (m_recvpacket, len, &icmpechoreply) ==-1) {//retry againrecvCount--; Continue;} Icmpechoreply.isreply = true;pingresult.icmpechoreplys.push_back (icmpechoreply); m_nreceived++;} Return true;} BOOL&NBSP;PING::GETSOCKADDR (CONST&NBSP;CHAR&NBSP;*&NBSP;HOSTORIP,&NBSP;STRUCT&NBSP;SOCKADDR_IN*&NBSP;SOCKADDR) {struct hostent *host;struct sockaddr_in dest_addr;unsigned long inaddr=0l ; Bzero (&DEST_ADDR,sizeof (DEST_ADDR));d est_addr.sin_family=af_inet;/* to determine whether the host name or IP address */if ( inaddr=inet_addr (Hostorip) ==inaddr_ NONE) { if ((Host=gethostbyname (Hostorip)) ==null) /* is host name */{ // printf ("gethostbyname error:%s\n", hostorip); return false;} memcpy ( (char *) &dest_addr.sin_addr,host->h_addr,host->h_length);} /* is the IP address */else if (!inet_aton (hostorip, &dest_addr.sin_addr)) { //memcpy ( ( char *) &dest_addr, (char *) &inaddr,host->h_length);//fprintf (stderr, "unknow Host:%s\n ", hostorip); return false;} *sockaddr = dest_addr;return true;} bool ping::p ing (std::string host, pingresult& pingresult) {return ping (host, 1, pingresult);} bool ping::p ing (std::string host, int count, pingresult& pingresult) { struct protoent *protocol;int size = 50 * 1024;icmpechoreply icmpechoreply;bool ret;m_nsend = 0;m_nreceived = 0; PingResult.icmpEchoReplys.clear (); M_maxpacketsize = count;m_pid = getpid (); pingresult.datalen = m_datalen;//if ( (Protocol = getprotobyname ("ICMP") ) ==NULL) {//perror ("Getprotobyname");//return false;//}/* generates an original socket using ICMP, which only root generates *///if ( (m_sockfd= Socket (Af_inet,sock_raw,protocol->p_proto) ) <0)//{////perror ("Socket error");//extern int errno;//pingresult.error = strerror (errno);//return false;//} if ((M_sockfd = socket (af_inet, sock_raw, ipproto_icmp)) <0) { perror ("Socket error"); }/* Expand socket receive buffer to 50K this is mainly to reduce the likelihood of receiving buffer overflow , if inadvertently ping a broadcast address or multicast address, will attract a large number of response */setsockopt (M_sockfd,sol_socket, so_rcvbuf,&size,sizeof (size) );/* Gets the process ID of main, the identifier for setting ICMP */if (!getsockaddr (Host.c_str (), &m_dest_addr)) {pingresult.error = "unknow host " &NBSP;+&NBSP;HOST;RETURN&NBSP;FALSE;} Pingresult.ip = inet_ntoa (M_DEST_ADDR.SIN_ADDR); Sendpacket (); /* sends all ICMP messages */recvpacket ( Pingresult); /* Receive all ICMP messages */pingresult.nsend = m_nsend;pingresult.nreceived = m_ Nreceived;close (M_SOCKFD); return true;}
Ping.h
#ifndef PING_H#define PING_H#include <stdio.h> #include <stdlib.h> #include <string.h> #include <signal.h> #include <sys/select.h> #include <arpa/ inet.h> #include <sys/types.h> #include <sys/time.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> #include <string> #include <vector> #define PACKET_SIZE 4096#define max_wait_time 5#define max_no_packets 3struct IcmpEchoReply {int icmpSeq;int icmpLen;int ipTtl;double rtt;std::string fromaddr;bool isreply;}; Struct pingresult {int datalen;int nsend;int nreceived;std::string ip;std::string error;std::vector<icmpechoreply> icmpechoreplys;}; Class ping {public:ping (); Bool ping (Std::string host, pingresult &pingresult ); bool ping (Std::string host, int count, pingresult& pingresult);p rivate: Unsigned short getchksum (Unsigned short *addr,int len); INT&NBSP;PACKICMP (int PACK_NO,&NBSP;STRUCT&NBSP;ICMP*&NBSP;ICMP); BOOL&NBSP;UNPACKICMP (char *buf,int len, struct icmpechoreply *icmpechoreply); Struct timeval tvsub (struct timeval timeval1,struct &NBSP;TIMEVAL&NBSP;TIMVAL2); Bool getsockaddr (const char * hostorip, sockaddr_in* &NBSP;SOCKADDR); Bool sendpacket (); Bool recvpacket (Pingresult &pingresult);p Rivate:char m_sendpacket[packet_size];char m_recvpacket[packet_size];int m_maxpacketsize;int m_sockfd ; int m_datalen;int m_nsend;int m_nreceived;int m_icmp_seq;struct sockaddr_in m_dest_addr;struct sockaddr_in m_from_addr;pid_t m_pid;}; #endif
Instance code:
if ( eth == false ) { char * hostOrIp = "192.168.1.20"; int nsend = 0, nreceived = 0; bool ret; PingResult pingResult; ping ping = ping (); for (int count = 1; count <= 4; count++) { ret = ping.ping (Hostorip, 1, pingresult); if (count == 1) { printf ("PING %s (%s): %d bytes data in icmp packets.\n ", hostorip, PingResult.ip.c_str (), pingresult.datalen); } if (!ret) { printf ("%s\n", pingresult.error.c_str ()); break; } showpingresult (Pingresult); nsend += pingResult.nsend; nreceived += pingResult.nreceived; } if (ret) { prinTF ("%d packets transmitted, %d received , %%%d lost\n", nsend, nreceived, (nsend - nreceived) / nsend * 100); eth = true; system ("echo 0 > /sys/class/gpio/gpio230/value "); // light 6 } else { printf ("-----------------eth0 Failed--------------\ n "); eth = false; system ("Echo 1 > /sys/class/gpio/gpio230/value "); // light 6 } }
This article is from the "Whylinux" blog, make sure to keep this source http://whylinux.blog.51cto.com/10900429/1902708
Ping Network test implemented by ARM Linux C + +