mirror of
https://github.com/reactos/reactos.git
synced 2024-06-26 07:51:52 +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
|
* PROJECT: ReactOS trace route utility
|
||||||
* LICENSE: GPL - See COPYING in the top level directory
|
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
|
||||||
* FILE: base/applications/network/tracert/tracert.cpp
|
|
||||||
* PURPOSE: Trace network paths through networks
|
* PURPOSE: Trace network paths through networks
|
||||||
* COPYRIGHT: Copyright 2018 Ged Murphy <gedmurphy@reactos.org>
|
* COPYRIGHT: Copyright 2018 Ged Murphy <gedmurphy@reactos.org>
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef __REACTOS__
|
#ifdef __REACTOS__
|
||||||
|
@ -275,15 +273,13 @@ PrintHopInfo(_In_ PVOID Buffer)
|
||||||
return (Status == 0);
|
return (Status == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static ULONG
|
||||||
DecodeResponse(
|
GetResponseStats(
|
||||||
_In_ PVOID ReplyBuffer,
|
_In_ PVOID ReplyBuffer,
|
||||||
_In_ bool OutputHopAddress,
|
_Out_ ULONG& RoundTripTime,
|
||||||
_Out_ bool& FoundTarget
|
_Out_ PVOID& AddressInfo
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
ULONG RoundTripTime;
|
|
||||||
PVOID AddressInfo;
|
|
||||||
ULONG Status;
|
ULONG Status;
|
||||||
|
|
||||||
if (Info.Family == AF_INET6)
|
if (Info.Family == AF_INET6)
|
||||||
|
@ -308,6 +304,22 @@ DecodeResponse(
|
||||||
AddressInfo = &EchoReplyV4->Address;
|
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)
|
switch (Status)
|
||||||
{
|
{
|
||||||
case IP_SUCCESS:
|
case IP_SUCCESS:
|
||||||
|
@ -320,6 +332,7 @@ DecodeResponse(
|
||||||
{
|
{
|
||||||
OutputText(IDS_HOP_ZERO);
|
OutputText(IDS_HOP_ZERO);
|
||||||
}
|
}
|
||||||
|
GoodResponse = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IP_DEST_HOST_UNREACHABLE:
|
case IP_DEST_HOST_UNREACHABLE:
|
||||||
|
@ -352,6 +365,10 @@ DecodeResponse(
|
||||||
|
|
||||||
if (OutputHopAddress)
|
if (OutputHopAddress)
|
||||||
{
|
{
|
||||||
|
if (Status == IP_REQ_TIMED_OUT && LastGoodResponse)
|
||||||
|
{
|
||||||
|
Status = GetResponseStats(LastGoodResponse, RoundTripTime, AddressInfo);
|
||||||
|
}
|
||||||
if (Status == IP_SUCCESS)
|
if (Status == IP_SUCCESS)
|
||||||
{
|
{
|
||||||
FoundTarget = true;
|
FoundTarget = true;
|
||||||
|
@ -374,18 +391,22 @@ static bool
|
||||||
RunTraceRoute()
|
RunTraceRoute()
|
||||||
{
|
{
|
||||||
bool Success = false;
|
bool Success = false;
|
||||||
|
PVOID ReplyBuffer = NULL, LastGoodResponse = NULL;
|
||||||
|
DWORD ReplySize;
|
||||||
|
|
||||||
|
HANDLE heap = GetProcessHeap();
|
||||||
|
bool Quit = false;
|
||||||
|
ULONG HopCount = 1;
|
||||||
|
bool FoundTarget = false;
|
||||||
|
|
||||||
Success = ResolveTarget();
|
Success = ResolveTarget();
|
||||||
if (!Success)
|
if (!Success)
|
||||||
{
|
{
|
||||||
OutputText(IDS_UNABLE_RESOLVE, Info.HostName);
|
OutputText(IDS_UNABLE_RESOLVE, Info.HostName);
|
||||||
return false;
|
goto Cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
BYTE SendBuffer[PACKET_SIZE];
|
ReplySize = PACKET_SIZE + SIZEOF_ICMP_ERROR + SIZEOF_IO_STATUS_BLOCK;
|
||||||
|
|
||||||
PVOID ReplyBuffer;
|
|
||||||
|
|
||||||
DWORD ReplySize = PACKET_SIZE + SIZEOF_ICMP_ERROR + SIZEOF_IO_STATUS_BLOCK;
|
|
||||||
if (Info.Family == AF_INET6)
|
if (Info.Family == AF_INET6)
|
||||||
{
|
{
|
||||||
ReplySize += sizeof(ICMPV6_ECHO_REPLY);
|
ReplySize += sizeof(ICMPV6_ECHO_REPLY);
|
||||||
|
@ -399,12 +420,11 @@ RunTraceRoute()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
HANDLE heap = GetProcessHeap();
|
|
||||||
ReplyBuffer = HeapAlloc(heap, HEAP_ZERO_MEMORY, ReplySize);
|
ReplyBuffer = HeapAlloc(heap, HEAP_ZERO_MEMORY, ReplySize);
|
||||||
if (ReplyBuffer == NULL)
|
if (ReplyBuffer == NULL)
|
||||||
{
|
{
|
||||||
FreeAddrInfoW(Info.Target);
|
Success = false;
|
||||||
return false;
|
goto Cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Info.Family == AF_INET6)
|
if (Info.Family == AF_INET6)
|
||||||
|
@ -417,9 +437,8 @@ RunTraceRoute()
|
||||||
}
|
}
|
||||||
if (Info.hIcmpFile == INVALID_HANDLE_VALUE)
|
if (Info.hIcmpFile == INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
HeapFree(heap, 0, ReplyBuffer);
|
Success = false;
|
||||||
FreeAddrInfoW(Info.Target);
|
goto Cleanup;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OutputText(IDS_TRACE_INFO, Info.HostName, Info.TargetIP, Info.MaxHops);
|
OutputText(IDS_TRACE_INFO, Info.HostName, Info.TargetIP, Info.MaxHops);
|
||||||
|
@ -427,15 +446,21 @@ RunTraceRoute()
|
||||||
IP_OPTION_INFORMATION IpOptionInfo;
|
IP_OPTION_INFORMATION IpOptionInfo;
|
||||||
ZeroMemory(&IpOptionInfo, sizeof(IpOptionInfo));
|
ZeroMemory(&IpOptionInfo, sizeof(IpOptionInfo));
|
||||||
|
|
||||||
bool Quit = false;
|
|
||||||
ULONG HopCount = 1;
|
|
||||||
bool FoundTarget = false;
|
|
||||||
while ((HopCount <= Info.MaxHops) && (FoundTarget == false) && (Quit == false))
|
while ((HopCount <= Info.MaxHops) && (FoundTarget == false) && (Quit == false))
|
||||||
{
|
{
|
||||||
OutputText(IDS_HOP_COUNT, HopCount);
|
OutputText(IDS_HOP_COUNT, HopCount);
|
||||||
|
|
||||||
|
if (LastGoodResponse)
|
||||||
|
{
|
||||||
|
HeapFree(heap, 0, LastGoodResponse);
|
||||||
|
LastGoodResponse = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
for (int Ping = 1; Ping <= NUM_OF_PINGS; Ping++)
|
for (int Ping = 1; Ping <= NUM_OF_PINGS; Ping++)
|
||||||
{
|
{
|
||||||
|
BYTE SendBuffer[PACKET_SIZE];
|
||||||
|
bool GoodResponse = false;
|
||||||
|
|
||||||
IpOptionInfo.Ttl = static_cast<UCHAR>(HopCount);
|
IpOptionInfo.Ttl = static_cast<UCHAR>(HopCount);
|
||||||
|
|
||||||
if (Info.Family == AF_INET6)
|
if (Info.Family == AF_INET6)
|
||||||
|
@ -473,7 +498,11 @@ RunTraceRoute()
|
||||||
Info.Timeout);
|
Info.Timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DecodeResponse(ReplyBuffer, (Ping == NUM_OF_PINGS), FoundTarget) == false)
|
if (DecodeResponse(ReplyBuffer,
|
||||||
|
LastGoodResponse,
|
||||||
|
(Ping == NUM_OF_PINGS),
|
||||||
|
GoodResponse,
|
||||||
|
FoundTarget) == false)
|
||||||
{
|
{
|
||||||
Quit = true;
|
Quit = true;
|
||||||
break;
|
break;
|
||||||
|
@ -484,6 +513,21 @@ RunTraceRoute()
|
||||||
Success = true;
|
Success = true;
|
||||||
break;
|
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++;
|
HopCount++;
|
||||||
|
@ -492,8 +536,19 @@ RunTraceRoute()
|
||||||
|
|
||||||
OutputText(IDS_TRACE_COMPLETE);
|
OutputText(IDS_TRACE_COMPLETE);
|
||||||
|
|
||||||
HeapFree(heap, 0, ReplyBuffer);
|
Cleanup:
|
||||||
FreeAddrInfoW(Info.Target);
|
if (ReplyBuffer)
|
||||||
|
{
|
||||||
|
HeapFree(heap, 0, ReplyBuffer);
|
||||||
|
}
|
||||||
|
if (LastGoodResponse)
|
||||||
|
{
|
||||||
|
HeapFree(heap, 0, LastGoodResponse);
|
||||||
|
}
|
||||||
|
if (Info.Target)
|
||||||
|
{
|
||||||
|
FreeAddrInfoW(Info.Target);
|
||||||
|
}
|
||||||
if (Info.hIcmpFile)
|
if (Info.hIcmpFile)
|
||||||
{
|
{
|
||||||
IcmpCloseHandle(Info.hIcmpFile);
|
IcmpCloseHandle(Info.hIcmpFile);
|
||||||
|
|
Loading…
Reference in a new issue