mirror of
https://github.com/reactos/reactos.git
synced 2024-06-17 10:01:58 +00:00
[TRACERT] Fix displaying hop address on last ping timeout
- Update source file header per coding rules - Store intermediate responses to display the hop address - Add separate function to get response stats from buffer - Add Cleanup label to free resources in a single place - Move local variables around to allow Cleanup goto CORE-18232
This commit is contained in:
parent
35a816a24e
commit
846c9aa1fd
|
@ -1,10 +1,8 @@
|
|||
/*
|
||||
* PROJECT: ReactOS trace route utility
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* FILE: base/applications/network/tracert/tracert.cpp
|
||||
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
|
||||
* PURPOSE: Trace network paths through networks
|
||||
* COPYRIGHT: Copyright 2018 Ged Murphy <gedmurphy@reactos.org>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef __REACTOS__
|
||||
|
@ -275,15 +273,13 @@ PrintHopInfo(_In_ PVOID Buffer)
|
|||
return (Status == 0);
|
||||
}
|
||||
|
||||
static bool
|
||||
DecodeResponse(
|
||||
static ULONG
|
||||
GetResponseStats(
|
||||
_In_ PVOID ReplyBuffer,
|
||||
_In_ bool OutputHopAddress,
|
||||
_Out_ bool& FoundTarget
|
||||
_Out_ ULONG& RoundTripTime,
|
||||
_Out_ PVOID& AddressInfo
|
||||
)
|
||||
{
|
||||
ULONG RoundTripTime;
|
||||
PVOID AddressInfo;
|
||||
ULONG Status;
|
||||
|
||||
if (Info.Family == AF_INET6)
|
||||
|
@ -308,6 +304,22 @@ DecodeResponse(
|
|||
AddressInfo = &EchoReplyV4->Address;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
static bool
|
||||
DecodeResponse(
|
||||
_In_ PVOID ReplyBuffer,
|
||||
_In_ PVOID LastGoodResponse,
|
||||
_In_ bool OutputHopAddress,
|
||||
_Out_ bool& GoodResponse,
|
||||
_Out_ bool& FoundTarget
|
||||
)
|
||||
{
|
||||
ULONG RoundTripTime;
|
||||
PVOID AddressInfo;
|
||||
ULONG Status = GetResponseStats(ReplyBuffer, RoundTripTime, AddressInfo);
|
||||
|
||||
switch (Status)
|
||||
{
|
||||
case IP_SUCCESS:
|
||||
|
@ -320,6 +332,7 @@ DecodeResponse(
|
|||
{
|
||||
OutputText(IDS_HOP_ZERO);
|
||||
}
|
||||
GoodResponse = true;
|
||||
break;
|
||||
|
||||
case IP_DEST_HOST_UNREACHABLE:
|
||||
|
@ -352,6 +365,10 @@ DecodeResponse(
|
|||
|
||||
if (OutputHopAddress)
|
||||
{
|
||||
if (Status == IP_REQ_TIMED_OUT && LastGoodResponse)
|
||||
{
|
||||
Status = GetResponseStats(LastGoodResponse, RoundTripTime, AddressInfo);
|
||||
}
|
||||
if (Status == IP_SUCCESS)
|
||||
{
|
||||
FoundTarget = true;
|
||||
|
@ -374,18 +391,22 @@ static bool
|
|||
RunTraceRoute()
|
||||
{
|
||||
bool Success = false;
|
||||
PVOID ReplyBuffer = NULL, LastGoodResponse = NULL;
|
||||
DWORD ReplySize;
|
||||
|
||||
HANDLE heap = GetProcessHeap();
|
||||
bool Quit = false;
|
||||
ULONG HopCount = 1;
|
||||
bool FoundTarget = false;
|
||||
|
||||
Success = ResolveTarget();
|
||||
if (!Success)
|
||||
{
|
||||
OutputText(IDS_UNABLE_RESOLVE, Info.HostName);
|
||||
return false;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
BYTE SendBuffer[PACKET_SIZE];
|
||||
|
||||
PVOID ReplyBuffer;
|
||||
|
||||
DWORD ReplySize = PACKET_SIZE + SIZEOF_ICMP_ERROR + SIZEOF_IO_STATUS_BLOCK;
|
||||
ReplySize = PACKET_SIZE + SIZEOF_ICMP_ERROR + SIZEOF_IO_STATUS_BLOCK;
|
||||
if (Info.Family == AF_INET6)
|
||||
{
|
||||
ReplySize += sizeof(ICMPV6_ECHO_REPLY);
|
||||
|
@ -399,12 +420,11 @@ RunTraceRoute()
|
|||
#endif
|
||||
}
|
||||
|
||||
HANDLE heap = GetProcessHeap();
|
||||
ReplyBuffer = HeapAlloc(heap, HEAP_ZERO_MEMORY, ReplySize);
|
||||
if (ReplyBuffer == NULL)
|
||||
{
|
||||
FreeAddrInfoW(Info.Target);
|
||||
return false;
|
||||
Success = false;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
if (Info.Family == AF_INET6)
|
||||
|
@ -417,9 +437,8 @@ RunTraceRoute()
|
|||
}
|
||||
if (Info.hIcmpFile == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
HeapFree(heap, 0, ReplyBuffer);
|
||||
FreeAddrInfoW(Info.Target);
|
||||
return false;
|
||||
Success = false;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
OutputText(IDS_TRACE_INFO, Info.HostName, Info.TargetIP, Info.MaxHops);
|
||||
|
@ -427,15 +446,21 @@ RunTraceRoute()
|
|||
IP_OPTION_INFORMATION IpOptionInfo;
|
||||
ZeroMemory(&IpOptionInfo, sizeof(IpOptionInfo));
|
||||
|
||||
bool Quit = false;
|
||||
ULONG HopCount = 1;
|
||||
bool FoundTarget = false;
|
||||
while ((HopCount <= Info.MaxHops) && (FoundTarget == false) && (Quit == false))
|
||||
{
|
||||
OutputText(IDS_HOP_COUNT, HopCount);
|
||||
|
||||
if (LastGoodResponse)
|
||||
{
|
||||
HeapFree(heap, 0, LastGoodResponse);
|
||||
LastGoodResponse = NULL;
|
||||
}
|
||||
|
||||
for (int Ping = 1; Ping <= NUM_OF_PINGS; Ping++)
|
||||
{
|
||||
BYTE SendBuffer[PACKET_SIZE];
|
||||
bool GoodResponse = false;
|
||||
|
||||
IpOptionInfo.Ttl = static_cast<UCHAR>(HopCount);
|
||||
|
||||
if (Info.Family == AF_INET6)
|
||||
|
@ -473,7 +498,11 @@ RunTraceRoute()
|
|||
Info.Timeout);
|
||||
}
|
||||
|
||||
if (DecodeResponse(ReplyBuffer, (Ping == NUM_OF_PINGS), FoundTarget) == false)
|
||||
if (DecodeResponse(ReplyBuffer,
|
||||
LastGoodResponse,
|
||||
(Ping == NUM_OF_PINGS),
|
||||
GoodResponse,
|
||||
FoundTarget) == false)
|
||||
{
|
||||
Quit = true;
|
||||
break;
|
||||
|
@ -484,6 +513,21 @@ RunTraceRoute()
|
|||
Success = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (GoodResponse)
|
||||
{
|
||||
if (LastGoodResponse)
|
||||
{
|
||||
HeapFree(heap, 0, LastGoodResponse);
|
||||
}
|
||||
LastGoodResponse = HeapAlloc(heap, HEAP_ZERO_MEMORY, ReplySize);
|
||||
if (LastGoodResponse == NULL)
|
||||
{
|
||||
Success = false;
|
||||
goto Cleanup;
|
||||
}
|
||||
CopyMemory(LastGoodResponse, ReplyBuffer, ReplySize);
|
||||
}
|
||||
}
|
||||
|
||||
HopCount++;
|
||||
|
@ -492,8 +536,19 @@ RunTraceRoute()
|
|||
|
||||
OutputText(IDS_TRACE_COMPLETE);
|
||||
|
||||
HeapFree(heap, 0, ReplyBuffer);
|
||||
FreeAddrInfoW(Info.Target);
|
||||
Cleanup:
|
||||
if (ReplyBuffer)
|
||||
{
|
||||
HeapFree(heap, 0, ReplyBuffer);
|
||||
}
|
||||
if (LastGoodResponse)
|
||||
{
|
||||
HeapFree(heap, 0, LastGoodResponse);
|
||||
}
|
||||
if (Info.Target)
|
||||
{
|
||||
FreeAddrInfoW(Info.Target);
|
||||
}
|
||||
if (Info.hIcmpFile)
|
||||
{
|
||||
IcmpCloseHandle(Info.hIcmpFile);
|
||||
|
|
Loading…
Reference in a new issue