ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

ping.c
Go to the documentation of this file.
00001 /*
00002  * COPYRIGHT:   See COPYING in the top level directory
00003  * PROJECT:     ReactOS ping utility
00004  * FILE:        base/applications/network/ping/ping.c
00005  * PURPOSE:     Network test utility
00006  * PROGRAMMERS:
00007  */
00008 
00009 #include <winsock2.h>
00010 #include <ws2tcpip.h>
00011 #include <tchar.h>
00012 #include <stdarg.h>
00013 #include <string.h>
00014 #include <stdio.h>
00015 #include "resource.h"
00016 
00017 #define NDEBUG
00018 
00019 /* General ICMP constants */
00020 #define ICMP_MINSIZE        8     /* Minimum ICMP packet size */
00021 #define ICMP_MAXSIZE        65535 /* Maximum ICMP packet size */
00022 
00023 /* ICMP message types */
00024 #define ICMPMSG_ECHOREQUEST 8     /* ICMP ECHO request message */
00025 #define ICMPMSG_ECHOREPLY   0     /* ICMP ECHO reply message */
00026 
00027 #pragma pack(4)
00028 
00029 /* IPv4 header structure */
00030 typedef struct _IPv4_HEADER
00031 {
00032     unsigned char IHL:4;
00033     unsigned char Version:4;
00034     unsigned char TOS;
00035     unsigned short Length;
00036     unsigned short Id;
00037     unsigned short FragFlags;
00038     unsigned char TTL;
00039     unsigned char Protocol;
00040     unsigned short Checksum;
00041     unsigned int SrcAddress;
00042     unsigned int DstAddress;
00043 } IPv4_HEADER, *PIPv4_HEADER;
00044 
00045 /* ICMP echo request/reply header structure */
00046 typedef struct _ICMP_HEADER
00047 {
00048     unsigned char Type;
00049     unsigned char Code;
00050     unsigned short Checksum;
00051     unsigned short Id;
00052     unsigned short SeqNum;
00053 } ICMP_HEADER, *PICMP_HEADER;
00054 
00055 typedef struct _ICMP_ECHO_PACKET
00056 {
00057     ICMP_HEADER Icmp;
00058 } ICMP_ECHO_PACKET, *PICMP_ECHO_PACKET;
00059 
00060 #pragma pack(1)
00061 
00062 BOOL                NeverStop;
00063 BOOL                ResolveAddresses;
00064 UINT                PingCount;
00065 UINT                DataSize;   /* ICMP echo request data size */
00066 BOOL                DontFragment;
00067 ULONG               TTLValue;
00068 ULONG               TOSValue;
00069 ULONG               Timeout;
00070 WCHAR               TargetName[256];
00071 SOCKET              IcmpSock;
00072 SOCKADDR_IN         Target;
00073 WCHAR               TargetIP[16];
00074 FD_SET              Fds;
00075 TIMEVAL             Timeval;
00076 UINT                CurrentSeqNum;
00077 UINT                SentCount;
00078 UINT                LostCount;
00079 BOOL                MinRTTSet;
00080 LARGE_INTEGER       MinRTT;     /* Minimum round trip time in microseconds */
00081 LARGE_INTEGER       MaxRTT;
00082 LARGE_INTEGER       SumRTT;
00083 LARGE_INTEGER       AvgRTT;
00084 LARGE_INTEGER       TicksPerMs; /* Ticks per millisecond */
00085 LARGE_INTEGER       TicksPerUs; /* Ticks per microsecond */
00086 LARGE_INTEGER       SentTime;
00087 BOOL                UsePerformanceCounter;
00088 HANDLE              hStdOutput;
00089 
00090 #ifndef NDEBUG
00091 /* Display the contents of a buffer */
00092 static VOID DisplayBuffer(
00093     PVOID Buffer,
00094     DWORD Size)
00095 {
00096     UINT i;
00097     PCHAR p;
00098 
00099     printf("Buffer (0x%p)  Size (0x%lX).\n", Buffer, Size);
00100 
00101     p = (PCHAR)Buffer;
00102     for (i = 0; i < Size; i++)
00103     {
00104         if (i % 16 == 0)
00105             printf("\n");
00106         printf("%02X ", (p[i]) & 0xFF);
00107     }
00108 }
00109 #endif /* !NDEBUG */
00110 
00111 LPWSTR
00112 MyLoadString(UINT uID)
00113 {
00114     HRSRC hres;
00115     HGLOBAL hResData;
00116     WCHAR *pwsz;
00117     UINT string_num, i;
00118 
00119     hres = FindResourceW(NULL, MAKEINTRESOURCEW((LOWORD(uID) >> 4) + 1), RT_STRING);
00120     if (!hres) return NULL;
00121 
00122     hResData = LoadResource(NULL, hres);
00123     if (!hResData) return NULL;
00124 
00125     pwsz = LockResource(hResData);
00126     if (!pwsz) return NULL;
00127     
00128     string_num = uID & 15;
00129     for (i = 0; i < string_num; i++)
00130         pwsz += *pwsz + 1;
00131 
00132     return pwsz + 1;
00133 }
00134 
00135 void FormatOutput(UINT uID, ...)
00136 {
00137     va_list valist;
00138 
00139     WCHAR Buf[1024];
00140     LPWSTR pBuf = Buf;
00141     LPWSTR Format;
00142     DWORD written;
00143     UINT DataLength;
00144 
00145     va_start(valist, uID);
00146 
00147     Format = MyLoadString(uID);
00148     if (!Format) return;
00149 
00150     DataLength = FormatMessage(FORMAT_MESSAGE_FROM_STRING, Format, 0, 0, Buf,\
00151                   sizeof(Buf) / sizeof(WCHAR), &valist);
00152 
00153     if(!DataLength)
00154     {
00155         if(GetLastError() != ERROR_INSUFFICIENT_BUFFER)
00156             return;
00157 
00158         DataLength = FormatMessage(FORMAT_MESSAGE_FROM_STRING |\
00159                                     FORMAT_MESSAGE_ALLOCATE_BUFFER,\
00160                                     Format, 0, 0, (LPWSTR)&pBuf, 0, &valist);
00161 
00162         if(!DataLength)
00163             return;
00164     }
00165 
00166     WriteConsole(hStdOutput, pBuf, DataLength, &written, NULL);
00167 
00168     if(pBuf != Buf)
00169         LocalFree(pBuf);
00170 }
00171 
00172 /* Display usage information on screen */
00173 static VOID Usage(VOID)
00174 {
00175     FormatOutput(IDS_USAGE);
00176 }
00177 
00178 /* Reset configuration to default values */
00179 static VOID Reset(VOID)
00180 {
00181     LARGE_INTEGER PerformanceCounterFrequency;
00182 
00183     NeverStop             = FALSE;
00184     ResolveAddresses      = FALSE;
00185     PingCount             = 4;
00186     DataSize              = 32;
00187     DontFragment          = FALSE;
00188     TTLValue              = 128;
00189     TOSValue              = 0;
00190     Timeout               = 1000;
00191     UsePerformanceCounter = QueryPerformanceFrequency(&PerformanceCounterFrequency);
00192 
00193     if (UsePerformanceCounter)
00194     {
00195         /* Performance counters may return incorrect results on some multiprocessor
00196            platforms so we restrict execution on the first processor. This may fail
00197            on Windows NT so we fall back to GetCurrentTick() for timing */
00198         if (SetThreadAffinityMask (GetCurrentThread(), 1) == 0)
00199             UsePerformanceCounter = FALSE;
00200 
00201         /* Convert frequency to ticks per millisecond */
00202         TicksPerMs.QuadPart = PerformanceCounterFrequency.QuadPart / 1000;
00203         /* And to ticks per microsecond */
00204         TicksPerUs.QuadPart = PerformanceCounterFrequency.QuadPart / 1000000;
00205     }
00206     if (!UsePerformanceCounter)
00207     {
00208         /* 1 tick per millisecond for GetCurrentTick() */
00209         TicksPerMs.QuadPart = 1;
00210         /* GetCurrentTick() cannot handle microseconds */
00211         TicksPerUs.QuadPart = 1;
00212     }
00213 }
00214 
00215 /* Parse command line parameters */
00216 static BOOL ParseCmdline(int argc, LPWSTR argv[])
00217 {
00218     INT i;
00219     BOOL FoundTarget = FALSE, InvalidOption = FALSE;
00220 
00221     if (argc < 2)
00222     {
00223         Usage();
00224         return FALSE;
00225     }
00226 
00227     for (i = 1; i < argc; i++)
00228     {
00229         if (argv[i][0] == L'-' || argv[i][0] == L'/')
00230         {
00231             switch (argv[i][1])
00232             {
00233                 case L't': NeverStop = TRUE; break;
00234                 case L'a': ResolveAddresses = TRUE; break;
00235                 case L'n':
00236                     if (i + 1 < argc)
00237                         PingCount = wcstoul(argv[++i], NULL, 0);
00238                     else
00239                         InvalidOption = TRUE;
00240                     break;
00241                 case L'l':
00242                     if (i + 1 < argc)
00243                     {
00244                         DataSize = wcstoul(argv[++i], NULL, 0);
00245                         
00246                         if (DataSize > ICMP_MAXSIZE - sizeof(ICMP_ECHO_PACKET) - sizeof(IPv4_HEADER))
00247                         {
00248                             FormatOutput(IDS_BAD_VALUE_OPTION_L, ICMP_MAXSIZE - \
00249                                          (int)sizeof(ICMP_ECHO_PACKET) - \
00250                                          (int)sizeof(IPv4_HEADER));
00251                             return FALSE;
00252                         }
00253                     } else
00254                         InvalidOption = TRUE;
00255                     break;
00256                 case L'f': DontFragment = TRUE; break;
00257                 case L'i':
00258                     if (i + 1 < argc)
00259                         TTLValue = wcstoul(argv[++i], NULL, 0);
00260                     else
00261                         InvalidOption = TRUE;
00262                     break;
00263                 case L'v':
00264                     if (i + 1 < argc)
00265                         TOSValue = wcstoul(argv[++i], NULL, 0);
00266                     else
00267                         InvalidOption = TRUE;
00268                     break;
00269                 case L'w':
00270                     if (i + 1 < argc)
00271                         Timeout = wcstoul(argv[++i], NULL, 0);
00272                     else
00273                         InvalidOption = TRUE;
00274                     break;
00275                 case '?':
00276                     Usage();
00277                     return FALSE;
00278                 default:
00279                     FormatOutput(IDS_BAD_OPTION, argv[i]);
00280                     return FALSE;
00281             }
00282             if (InvalidOption)
00283             {
00284                 FormatOutput(IDS_BAD_OPTION_FORMAT, argv[i]);
00285                 return FALSE;
00286             }
00287         }
00288         else
00289         {
00290             if (FoundTarget)
00291             {
00292                 FormatOutput(IDS_BAD_PARAMETER, argv[i]);
00293                 return FALSE;
00294             }
00295             else
00296             {
00297                 wcscpy(TargetName, argv[i]);
00298                 FoundTarget = TRUE;
00299             }
00300         }
00301     }
00302 
00303     if (!FoundTarget)
00304     {
00305         FormatOutput(IDS_DEST_MUST_BE_SPECIFIED);
00306         return FALSE;
00307     }
00308 
00309     return TRUE;
00310 }
00311 
00312 /* Calculate checksum of data */
00313 static WORD Checksum(PUSHORT data, UINT size)
00314 {
00315     ULONG sum = 0;
00316 
00317     while (size > 1)
00318     {
00319         sum  += *data++;
00320         size -= sizeof(USHORT);
00321     }
00322 
00323     if (size)
00324         sum += *(UCHAR*)data;
00325 
00326     sum = (sum >> 16) + (sum & 0xFFFF);
00327     sum += (sum >> 16);
00328 
00329     return (USHORT)(~sum);
00330 }
00331 
00332 /* Prepare to ping target */
00333 static BOOL Setup(VOID)
00334 {
00335     WORD     wVersionRequested;
00336     WSADATA  WsaData;
00337     INT      Status;
00338     ULONG    Addr;
00339     PHOSTENT phe;
00340     CHAR     aTargetName[256];
00341 
00342     wVersionRequested = MAKEWORD(2, 2);
00343 
00344     Status = WSAStartup(wVersionRequested, &WsaData);
00345     if (Status != 0)
00346     {
00347         FormatOutput(IDS_COULD_NOT_INIT_WINSOCK);
00348         return FALSE;
00349     }
00350 
00351     IcmpSock = WSASocket(AF_INET, SOCK_RAW, IPPROTO_ICMP, NULL, 0, 0);
00352     if (IcmpSock == INVALID_SOCKET)
00353     {
00354         FormatOutput(IDS_COULD_NOT_CREATE_SOCKET, WSAGetLastError());
00355         return FALSE;
00356     }
00357 
00358     if (setsockopt(IcmpSock,
00359                    IPPROTO_IP,
00360                    IP_DONTFRAGMENT,
00361                    (const char *)&DontFragment,
00362                    sizeof(DontFragment)) == SOCKET_ERROR)
00363     {
00364         FormatOutput(IDS_SETSOCKOPT_FAILED, WSAGetLastError());
00365         return FALSE;
00366     }
00367 
00368     if (setsockopt(IcmpSock,
00369                    IPPROTO_IP,
00370                    IP_TTL,
00371                    (const char *)&TTLValue,
00372                    sizeof(TTLValue)) == SOCKET_ERROR)
00373     {
00374         FormatOutput(IDS_SETSOCKOPT_FAILED, WSAGetLastError());
00375         return FALSE;
00376     }
00377 
00378 
00379     if(!WideCharToMultiByte(CP_ACP, 0, TargetName, -1, aTargetName,\
00380                             sizeof(aTargetName), NULL, NULL))
00381     {
00382         FormatOutput(IDS_UNKNOWN_HOST, TargetName);
00383         return FALSE;
00384     }
00385 
00386     ZeroMemory(&Target, sizeof(Target));
00387     phe = NULL;
00388     Addr = inet_addr(aTargetName);
00389     if (Addr == INADDR_NONE)
00390     {
00391         phe = gethostbyname(aTargetName);
00392         if (phe == NULL)
00393         {
00394             FormatOutput(IDS_UNKNOWN_HOST, TargetName);
00395             return FALSE;
00396         }
00397 
00398         CopyMemory(&Target.sin_addr, phe->h_addr, phe->h_length);
00399         Target.sin_family = phe->h_addrtype;
00400     }
00401     else
00402     {
00403         Target.sin_addr.s_addr = Addr;
00404         Target.sin_family = AF_INET;
00405     }
00406 
00407 
00408     swprintf(TargetIP, L"%d.%d.%d.%d", Target.sin_addr.S_un.S_un_b.s_b1,\
00409                                        Target.sin_addr.S_un.S_un_b.s_b2,\
00410                                        Target.sin_addr.S_un.S_un_b.s_b3,\
00411                                        Target.sin_addr.S_un.S_un_b.s_b4);
00412     CurrentSeqNum = 1;
00413     SentCount = 0;
00414     LostCount = 0;
00415     MinRTT.QuadPart = 0;
00416     MaxRTT.QuadPart = 0;
00417     SumRTT.QuadPart = 0;
00418     MinRTTSet       = FALSE;
00419     return TRUE;
00420 }
00421 
00422 /* Close socket */
00423 static VOID Cleanup(VOID)
00424 {
00425     if (IcmpSock != INVALID_SOCKET)
00426         closesocket(IcmpSock);
00427 
00428     WSACleanup();
00429 }
00430 
00431 static VOID QueryTime(PLARGE_INTEGER Time)
00432 {
00433     if (UsePerformanceCounter)
00434     {
00435         if (QueryPerformanceCounter(Time) == 0)
00436         {
00437             /* This should not happen, but we fall
00438                back to GetCurrentTick() if it does */
00439             Time->u.LowPart  = (ULONG)GetTickCount();
00440             Time->u.HighPart = 0;
00441 
00442             /* 1 tick per millisecond for GetCurrentTick() */
00443             TicksPerMs.QuadPart = 1;
00444             /* GetCurrentTick() cannot handle microseconds */
00445             TicksPerUs.QuadPart = 1;
00446 
00447             UsePerformanceCounter = FALSE;
00448         }
00449     }
00450     else
00451     {
00452         Time->u.LowPart  = (ULONG)GetTickCount();
00453         Time->u.HighPart = 0;
00454     }
00455 }
00456 
00457 static VOID TimeToMsString(LPWSTR String, LARGE_INTEGER Time)
00458 {
00459     WCHAR         Convstr[40];
00460     LARGE_INTEGER LargeTime;
00461     LPWSTR ms;
00462 
00463     LargeTime.QuadPart = Time.QuadPart / TicksPerMs.QuadPart;
00464 
00465     _i64tow(LargeTime.QuadPart, Convstr, 10);
00466     wcscpy(String, Convstr);
00467     ms = MyLoadString(IDS_MS);
00468     wcscat(String, ms);
00469 }
00470 
00471 /* Locate the ICMP data and print it. Returns TRUE if the packet was good,
00472    FALSE if not */
00473 static BOOL DecodeResponse(PCHAR buffer, UINT size, PSOCKADDR_IN from)
00474 {
00475     PIPv4_HEADER      IpHeader;
00476     PICMP_ECHO_PACKET Icmp;
00477     UINT              IphLength;
00478     WCHAR             Time[100];
00479     LARGE_INTEGER     RelativeTime;
00480     LARGE_INTEGER     LargeTime;
00481     WCHAR             Sign[2];
00482     WCHAR wfromIP[16];
00483 
00484     IpHeader = (PIPv4_HEADER)buffer;
00485 
00486     IphLength = IpHeader->IHL * 4;
00487 
00488     if (size  < IphLength + ICMP_MINSIZE)
00489     {
00490 #ifndef NDEBUG
00491         printf("Bad size (0x%X < 0x%X)\n", size, IphLength + ICMP_MINSIZE);
00492 #endif /* !NDEBUG */
00493         return FALSE;
00494     }
00495 
00496     Icmp = (PICMP_ECHO_PACKET)(buffer + IphLength);
00497 
00498     if (Icmp->Icmp.Type != ICMPMSG_ECHOREPLY)
00499     {
00500 #ifndef NDEBUG
00501         printf("Bad ICMP type (0x%X should be 0x%X)\n", Icmp->Icmp.Type, ICMPMSG_ECHOREPLY);
00502 #endif /* !NDEBUG */
00503         return FALSE;
00504     }
00505 
00506     if (Icmp->Icmp.Id != (USHORT)GetCurrentProcessId())
00507     {
00508 #ifndef NDEBUG
00509         printf("Bad ICMP id (0x%X should be 0x%X)\n", Icmp->Icmp.Id, (USHORT)GetCurrentProcessId());
00510 #endif /* !NDEBUG */
00511         return FALSE;
00512     }
00513 
00514     if (from->sin_addr.s_addr != Target.sin_addr.s_addr)
00515     {
00516 #ifndef NDEBUG
00517         printf("Bad source address (%s should be %s)\n", inet_ntoa(from->sin_addr), inet_ntoa(Target.sin_addr));
00518 #endif /* !NDEBUG */
00519         return FALSE;
00520     }
00521 
00522     QueryTime(&LargeTime);
00523 
00524     RelativeTime.QuadPart = (LargeTime.QuadPart - SentTime.QuadPart);
00525 
00526     if ((RelativeTime.QuadPart / TicksPerMs.QuadPart) < 1)
00527     {
00528         LPWSTR ms1;
00529 
00530         wcscpy(Sign, L"<");
00531         ms1 = MyLoadString(IDS_1MS);
00532         wcscpy(Time, ms1);
00533     }
00534     else
00535     {
00536         wcscpy(Sign, L"=");
00537         TimeToMsString(Time, RelativeTime);
00538     }
00539 
00540 
00541     swprintf(wfromIP, L"%d.%d.%d.%d", from->sin_addr.S_un.S_un_b.s_b1,\
00542                                       from->sin_addr.S_un.S_un_b.s_b2,\
00543                                       from->sin_addr.S_un.S_un_b.s_b3,\
00544                                       from->sin_addr.S_un.S_un_b.s_b4);
00545     FormatOutput(IDS_REPLY_FROM, wfromIP,\
00546                  size - IphLength - (int)sizeof(ICMP_ECHO_PACKET),\
00547                  Sign, Time, IpHeader->TTL);
00548 
00549     if (RelativeTime.QuadPart < MinRTT.QuadPart || !MinRTTSet)
00550     {
00551         MinRTT.QuadPart = RelativeTime.QuadPart;
00552         MinRTTSet = TRUE;
00553     }
00554     if (RelativeTime.QuadPart > MaxRTT.QuadPart)
00555         MaxRTT.QuadPart = RelativeTime.QuadPart;
00556 
00557     SumRTT.QuadPart += RelativeTime.QuadPart;
00558 
00559     return TRUE;
00560 }
00561 
00562 /* Send and receive one ping */
00563 static BOOL Ping(VOID)
00564 {
00565     INT                 Status;
00566     SOCKADDR            From;
00567     INT                 Length;
00568     PVOID               Buffer;
00569     UINT                Size;
00570     PICMP_ECHO_PACKET   Packet;
00571 
00572     /* Account for extra space for IP header when packet is received */
00573     Size   = DataSize + 128;
00574     Buffer = GlobalAlloc(0, Size);
00575     if (!Buffer)
00576     {
00577         FormatOutput(IDS_NOT_ENOUGH_RESOURCES);
00578         return FALSE;
00579     }
00580 
00581     ZeroMemory(Buffer, Size);
00582     Packet = (PICMP_ECHO_PACKET)Buffer;
00583 
00584     /* Assemble ICMP echo request packet */
00585     Packet->Icmp.Type     = ICMPMSG_ECHOREQUEST;
00586     Packet->Icmp.Code     = 0;
00587     Packet->Icmp.Id       = (USHORT)GetCurrentProcessId();
00588     Packet->Icmp.SeqNum   = htons((USHORT)CurrentSeqNum);
00589     Packet->Icmp.Checksum = 0;
00590 
00591     /* Calculate checksum for ICMP header and data area */
00592     Packet->Icmp.Checksum = Checksum((PUSHORT)&Packet->Icmp, sizeof(ICMP_ECHO_PACKET) + DataSize);
00593 
00594     CurrentSeqNum++;
00595 
00596     /* Send ICMP echo request */
00597 
00598     FD_ZERO(&Fds);
00599     FD_SET(IcmpSock, &Fds);
00600     Timeval.tv_sec  = Timeout / 1000;
00601     Timeval.tv_usec = Timeout % 1000;
00602     Status = select(0, NULL, &Fds, NULL, &Timeval);
00603     if ((Status != SOCKET_ERROR) && (Status != 0))
00604     {
00605 
00606 #ifndef NDEBUG
00607         printf("Sending packet\n");
00608         DisplayBuffer(Buffer, sizeof(ICMP_ECHO_PACKET) + DataSize);
00609         printf("\n");
00610 #endif /* !NDEBUG */
00611 
00612         Status = sendto(IcmpSock, Buffer, sizeof(ICMP_ECHO_PACKET) + DataSize,
00613             0, (SOCKADDR*)&Target, sizeof(Target));
00614         QueryTime(&SentTime);
00615         SentCount++;
00616     }
00617     if (Status == SOCKET_ERROR)
00618     {
00619         if (WSAGetLastError() == WSAEHOSTUNREACH)
00620             FormatOutput(IDS_DEST_UNREACHABLE);
00621         else
00622             FormatOutput(IDS_COULD_NOT_TRANSMIT, WSAGetLastError());
00623         GlobalFree(Buffer);
00624         return FALSE;
00625     }
00626 
00627     /* Expect to receive ICMP echo reply */
00628     FD_ZERO(&Fds);
00629     FD_SET(IcmpSock, &Fds);
00630     Timeval.tv_sec  = Timeout / 1000;
00631     Timeval.tv_usec = Timeout % 1000;
00632 
00633     do {
00634         Status = select(0, &Fds, NULL, NULL, &Timeval);
00635         if ((Status != SOCKET_ERROR) && (Status != 0))
00636         {
00637             Length = sizeof(From);
00638             Status = recvfrom(IcmpSock, Buffer, Size, 0, &From, &Length);
00639 
00640 #ifndef NDEBUG
00641             printf("Received packet\n");
00642             DisplayBuffer(Buffer, Status);
00643             printf("\n");
00644 #endif /* !NDEBUG */
00645         }
00646         else
00647             LostCount++;
00648         if (Status == SOCKET_ERROR)
00649         {
00650             if (WSAGetLastError() != WSAETIMEDOUT)
00651             {
00652                 FormatOutput(IDS_COULD_NOT_RECV, WSAGetLastError());
00653                 GlobalFree(Buffer);
00654                 return FALSE;
00655             }
00656             Status = 0;
00657         }
00658 
00659         if (Status == 0)
00660         {
00661             FormatOutput(IDS_REQUEST_TIMEOUT);
00662             GlobalFree(Buffer);
00663             return TRUE;
00664         }
00665 
00666     } while (!DecodeResponse(Buffer, Status, (PSOCKADDR_IN)&From));
00667 
00668     GlobalFree(Buffer);
00669     return TRUE;
00670 }
00671 
00672 
00673 /* Program entry point */
00674 int wmain(int argc, LPWSTR argv[])
00675 {
00676     UINT Count;
00677     WCHAR MinTime[20];
00678     WCHAR MaxTime[20];
00679     WCHAR AvgTime[20];
00680 
00681     hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
00682 
00683     Reset();
00684 
00685     if ((ParseCmdline(argc, argv)) && (Setup()))
00686     {
00687 
00688         FormatOutput(IDS_PING_WITH_BYTES, TargetName, TargetIP, DataSize);
00689 
00690         Count = 0;
00691         while ((NeverStop) || (Count < PingCount))
00692         {
00693             Ping();
00694             Count++;
00695             if((NeverStop) || (Count < PingCount))
00696                 Sleep(Timeout);
00697         };
00698 
00699         Cleanup();
00700 
00701         /* Calculate avarage round trip time */
00702         if ((SentCount - LostCount) > 0)
00703             AvgRTT.QuadPart = SumRTT.QuadPart / (SentCount - LostCount);
00704         else
00705             AvgRTT.QuadPart = 0;
00706 
00707         /* Calculate loss percent */
00708         Count = SentCount ? (LostCount * 100) / SentCount : 0;
00709 
00710         if (!MinRTTSet)
00711             MinRTT = MaxRTT;
00712 
00713         TimeToMsString(MinTime, MinRTT);
00714         TimeToMsString(MaxTime, MaxRTT);
00715         TimeToMsString(AvgTime, AvgRTT);
00716 
00717         /* Print statistics */
00718         FormatOutput(IDS_PING_STATISTICS, TargetIP);
00719         FormatOutput(IDS_PACKETS_SENT_RECEIVED_LOST,\
00720                      SentCount, SentCount - LostCount, LostCount, Count);
00721 
00722 
00723         /* Print approximate times or NO approximate times if 100% loss */
00724         if ((SentCount - LostCount) > 0)
00725         {
00726             FormatOutput(IDS_APPROXIMATE_ROUND_TRIP);
00727             FormatOutput(IDS_MIN_MAX_AVERAGE, MinTime, MaxTime, AvgTime);
00728         }
00729     }
00730     else
00731     {
00732         return 1;
00733     }
00734     return 0;
00735 }
00736 
00737 /* EOF */

Generated on Sat May 26 2012 04:16:10 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.