- Fix calculation of the maximum data size (it previously calculated 65519 (0xFFFF - sizeof(ICMPv4Header) - sizeof(LARGE_INTEGER)) which was wrong because the real maximum was 65499 (0xFFFF - sizeof(IPv4Header) - sizeof(ICMPv4Header) - sizeof(LARGE_INTEGER)))

- Implement -f and -i options
 - Note: This raises our max ping data size to 65507 (0xFFFF - sizeof(IPv4Header) - sizeof(ICMPv4Header)) so we match linux's (iputils) ping max size but Windows' max is 65500 and I'm not sure if we should change our code to match Windows or not

svn path=/branches/aicom-network-branch/; revision=45129
This commit is contained in:
Cameron Gutman 2010-01-18 00:52:31 +00:00
parent 3a3d5b8571
commit eaf8ca78e4

View file

@ -7,6 +7,7 @@
*/
#include <winsock2.h>
#include <ws2tcpip.h>
#include <tchar.h>
#include <stdarg.h>
#include <string.h>
@ -53,7 +54,6 @@ typedef struct _ICMP_HEADER
typedef struct _ICMP_ECHO_PACKET
{
ICMP_HEADER Icmp;
LARGE_INTEGER Timestamp;
} ICMP_ECHO_PACKET, *PICMP_ECHO_PACKET;
#pragma pack(1)
@ -83,6 +83,7 @@ LARGE_INTEGER SumRTT;
LARGE_INTEGER AvgRTT;
LARGE_INTEGER TicksPerMs; /* Ticks per millisecond */
LARGE_INTEGER TicksPerUs; /* Ticks per microsecond */
LARGE_INTEGER SentTime;
BOOL UsePerformanceCounter;
#ifndef NDEBUG
@ -218,10 +219,10 @@ static BOOL ParseCmdline(int argc, char* argv[])
case 'n': PingCount = GetULONG2(&argv[i][2], argv[i + 1], &i); break;
case 'l':
DataSize = GetULONG2(&argv[i][2], argv[i + 1], &i);
if (DataSize > ICMP_MAXSIZE - sizeof(ICMP_ECHO_PACKET))
if (DataSize > ICMP_MAXSIZE - sizeof(ICMP_ECHO_PACKET) - sizeof(IPv4_HEADER))
{
printf("Bad value for option -l, valid range is from 0 to %d.\n",
ICMP_MAXSIZE - (int)sizeof(ICMP_ECHO_PACKET));
ICMP_MAXSIZE - (int)sizeof(ICMP_ECHO_PACKET) - (int)sizeof(IPv4_HEADER));
return FALSE;
}
break;
@ -314,6 +315,27 @@ static BOOL Setup(VOID)
return FALSE;
}
if (setsockopt(IcmpSock,
IPPROTO_IP,
IP_DONTFRAGMENT,
(const char *)&DontFragment,
sizeof(DontFragment)) == SOCKET_ERROR)
{
printf("setsockopt failed (%d).\n", WSAGetLastError());
return FALSE;
}
if (setsockopt(IcmpSock,
IPPROTO_IP,
IP_TTL,
(const char *)&TTLValue,
sizeof(TTLValue)) == SOCKET_ERROR)
{
printf("setsockopt failed (%d).\n", WSAGetLastError());
return FALSE;
}
ZeroMemory(&Target, sizeof(Target));
phe = NULL;
Addr = inet_addr(TargetName);
@ -447,7 +469,7 @@ static BOOL DecodeResponse(PCHAR buffer, UINT size, PSOCKADDR_IN from)
QueryTime(&LargeTime);
RelativeTime.QuadPart = (LargeTime.QuadPart - Icmp->Timestamp.QuadPart);
RelativeTime.QuadPart = (LargeTime.QuadPart - SentTime.QuadPart);
if ((RelativeTime.QuadPart / TicksPerMs.QuadPart) < 1)
{
@ -505,10 +527,6 @@ static BOOL Ping(VOID)
Packet->Icmp.SeqNum = htons((USHORT)CurrentSeqNum);
Packet->Icmp.Checksum = 0;
/* Timestamp is part of data area */
QueryTime(&Packet->Timestamp);
CopyMemory(Buffer, &Packet->Icmp, sizeof(ICMP_ECHO_PACKET) + DataSize);
/* Calculate checksum for ICMP header and data area */
Packet->Icmp.Checksum = Checksum((PUSHORT)&Packet->Icmp, sizeof(ICMP_ECHO_PACKET) + DataSize);
@ -532,6 +550,7 @@ static BOOL Ping(VOID)
Status = sendto(IcmpSock, Buffer, sizeof(ICMP_ECHO_PACKET) + DataSize,
0, (SOCKADDR*)&Target, sizeof(Target));
QueryTime(&SentTime);
SentCount++;
}
if (Status == SOCKET_ERROR)