Ticket #7764: 7764-ping_win32.patch

File 7764-ping_win32.patch, 4.7 KB (added by Jeff Lu <jll544@…>, 14 years ago)
  • libs/libmyth/util.cpp

     
    862862    return false;
    863863}
    864864
    865 #ifdef USING_MINGW
    866 u_short in_cksum(u_short *addr, int len)
    867 {
    868     register int nleft = len;
    869     register u_short *w = addr;
    870     register u_short answer;
    871     register int sum = 0;
    872 
    873     /*
    874      *  Our algorithm is simple, using a 32 bit accumulator (sum),
    875      *  we add sequential 16 bit words to it, and at the end, fold
    876      *  back all the carry bits from the top 16 bits into the lower
    877      *  16 bits.
    878      */
    879     while (nleft > 1)
    880     {
    881         sum += *w++;
    882         nleft -= 2;
    883     }
    884 
    885     /* mop up an odd byte, if necessary */
    886     if (nleft == 1)
    887     {
    888         u_short u = 0;
    889 
    890         *(u_char *)(&u) = *(u_char *)w ;
    891         sum += u;
    892     }
    893 
    894     /*
    895      * add back carry outs from top 16 bits to low 16 bits
    896      */
    897     sum = (sum >> 16) + (sum & 0xffff);  /* add hi 16 to low 16 */
    898     sum += (sum >> 16);                  /* add carry */
    899     answer = ~sum;                       /* truncate to 16 bits */
    900     return (answer);
    901 }
    902 #endif
    903 
    904865/**
    905866 * \brief Can we ping host within timeout seconds?
    906867 */
    907868bool ping(const QString &host, int timeout)
    908869{
    909870#ifdef USING_MINGW
    910     VERBOSE(VB_SOCKET, QString("Ping: pinging %1 (%2 seconds max)")
    911                        .arg(host).arg(timeout));
    912     SOCKET    rawSocket;
    913     LPHOSTENT lpHost;
    914     struct    sockaddr_in saDest;
     871    QString cmd = QString("%systemroot%\\system32\\ping.exe -i %1 -n 1 %2>NUL")
     872                  .arg(timeout).arg(host);
    915873
    916     #define ICMP_ECHOREPLY 0
    917     #define ICMP_ECHOREQ   8
    918     struct IPHDR {
    919         u_char         VIHL;     // Version and IHL
    920         u_char         TOS;      // Type Of Service
    921         short          TotLen;   // Total Length
    922         short          ID;       // Identification
    923         short          FlagOff;  // Flags and Fragment Offset
    924         u_char         TTL;      // Time To Live
    925         u_char         Protocol; // Protocol
    926         u_short        Checksum; // Checksum
    927         struct in_addr iaSrc;    // Internet Address - Source
    928         struct in_addr iaDst;    // Internet Address - Destination
    929     };
    930     struct ICMPHDR {
    931         u_char  Type;            // Type
    932         u_char  Code;            // Code
    933         u_short Checksum;        // Checksum
    934         u_short ID;              // Identification
    935         u_short Seq;             // Sequence
    936         char    Data;            // Data
    937     };
    938 
    939     struct Request {
    940         ICMPHDR icmpHdr;
    941         DWORD   dwTime;
    942         char    cData[32];
    943     };
    944     struct Reply {
    945         IPHDR   ipHdr;
    946         Request echoRequest;
    947         char    cFiller[256];
    948     };
    949 
    950     if (INVALID_SOCKET == (rawSocket = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)))
    951     {
    952         VERBOSE(VB_SOCKET, "Ping: can't create socket");
     874    if (myth_system(cmd))
    953875        return false;
    954     }
    955 
    956     lpHost = gethostbyname(host.toLocal8Bit().constData());
    957     if (!lpHost)
    958     {
    959         VERBOSE(VB_SOCKET, "Ping: gethostbyname failed");
    960         closesocket(rawSocket);
    961         return false;
    962     }
    963 
    964     saDest.sin_addr.s_addr = *((u_long FAR *) (lpHost->h_addr));
    965     saDest.sin_family      = AF_INET;
    966     saDest.sin_port        = 0;
    967 
    968     Request echoReq;
    969     echoReq.icmpHdr.Type = ICMP_ECHOREQ;
    970     echoReq.icmpHdr.Code = 0;
    971     echoReq.icmpHdr.ID   = 123;
    972     echoReq.icmpHdr.Seq  = 456;
    973     for (unsigned i = 0; i < sizeof(echoReq.cData); i++)
    974         echoReq.cData[i] = ' ' + i;
    975     echoReq.dwTime = GetTickCount();
    976     echoReq.icmpHdr.Checksum = in_cksum((u_short *)&echoReq, sizeof(Request));
    977 
    978     if (SOCKET_ERROR == sendto(rawSocket, (LPSTR)&echoReq, sizeof(Request),
    979                                0, (LPSOCKADDR)&saDest, sizeof(SOCKADDR_IN)))
    980     {
    981         VERBOSE(VB_SOCKET, "Ping: send failed");
    982         closesocket(rawSocket);
    983         return false;
    984     }
    985 
    986     struct timeval Timeout;
    987     fd_set readfds;
    988     readfds.fd_count = 1;
    989     readfds.fd_array[0] = rawSocket;
    990     Timeout.tv_sec  = timeout;
    991     Timeout.tv_usec = 0;
    992 
    993     if (SOCKET_ERROR == select(1, &readfds, NULL, NULL, &Timeout))
    994     {
    995         VERBOSE(VB_SOCKET, "Ping: timeout expired or select failed");
    996         closesocket(rawSocket);
    997         return false;
    998     }
    999 
    1000     closesocket(rawSocket);
    1001     VERBOSE(VB_SOCKET, "Ping: done");
    1002     return true;
    1003876#else
    1004877    QString cmd = QString("ping -t %1 -c 1  %2  >/dev/null 2>&1")
    1005878                  .arg(timeout).arg(host);
     
    1013886        if (myth_system(cmd))
    1014887            return false;
    1015888    }
     889#endif
    1016890
    1017891    return true;
    1018 #endif
    1019892}
    1020893
    1021894/**