Ping Network test implemented by ARM Linux C + +

Source: Internet
Author: User
Tags ping network

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&AMP;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 (&AMP;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 + +

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.