ReactOS 0.4.16-dev-1020-gf135cab
tracert.cpp File Reference
#include <winsock2.h>
#include <Windows.h>
#include <ws2tcpip.h>
#include <iphlpapi.h>
#include <icmpapi.h>
#include <strsafe.h>
#include <errno.h>
#include "resource.h"
Include dependency graph for tracert.cpp:

Go to the source code of this file.

Classes

struct  TraceInfo
 

Macros

#define SIZEOF_ICMP_ERROR   8
 
#define SIZEOF_IO_STATUS_BLOCK   8
 
#define PACKET_SIZE   32
 
#define MAX_IPADDRESS   32
 
#define NUM_OF_PINGS   3
 
#define MIN_HOP_COUNT   1
 
#define MAX_HOP_COUNT   255
 
#define MIN_MILLISECONDS   1
 
#define MAX_MILLISECONDS   ULONG_MAX
 

Functions

static INT LengthOfStrResource (_In_ HINSTANCE hInst, _In_ UINT uID)
 
static INT AllocAndLoadString (_In_ UINT uID, _Out_ LPWSTR *lpTarget)
 
static INT OutputText (_In_ UINT uID,...)
 
static VOID Usage ()
 
static bool GetULONG (_In_ PCWSTR String, _Out_ PULONG Value)
 
static bool ResolveTarget ()
 
static bool PrintHopInfo (_In_ PVOID Buffer)
 
static ULONG GetResponseStats (_In_ PVOID ReplyBuffer, _Out_ ULONG &RoundTripTime, _Out_ PVOID &AddressInfo)
 
static bool DecodeResponse (_In_ PVOID ReplyBuffer, _In_ PVOID LastGoodResponse, _In_ bool OutputHopAddress, _Out_ bool &GoodResponse, _Out_ bool &FoundTarget)
 
static bool RunTraceRoute ()
 
static bool GetUlongOptionInRange (_In_ int argc, _In_ wchar_t *argv[], _Inout_ int *i, _Out_ ULONG *Value, _In_ ULONG MinimumValue, _In_ ULONG MaximumValue)
 
static bool ParseCmdline (int argc, wchar_t *argv[])
 
EXTERN_C int wmain (int argc, wchar_t *argv[])
 

Variables

struct TraceInfo Info = { 0 }
 

Macro Definition Documentation

◆ MAX_HOP_COUNT

#define MAX_HOP_COUNT   255

Definition at line 37 of file tracert.cpp.

◆ MAX_IPADDRESS

#define MAX_IPADDRESS   32

Definition at line 34 of file tracert.cpp.

◆ MAX_MILLISECONDS

#define MAX_MILLISECONDS   ULONG_MAX

Definition at line 39 of file tracert.cpp.

◆ MIN_HOP_COUNT

#define MIN_HOP_COUNT   1

Definition at line 36 of file tracert.cpp.

◆ MIN_MILLISECONDS

#define MIN_MILLISECONDS   1

Definition at line 38 of file tracert.cpp.

◆ NUM_OF_PINGS

#define NUM_OF_PINGS   3

Definition at line 35 of file tracert.cpp.

◆ PACKET_SIZE

#define PACKET_SIZE   32

Definition at line 33 of file tracert.cpp.

◆ SIZEOF_ICMP_ERROR

#define SIZEOF_ICMP_ERROR   8

Definition at line 31 of file tracert.cpp.

◆ SIZEOF_IO_STATUS_BLOCK

#define SIZEOF_IO_STATUS_BLOCK   8

Definition at line 32 of file tracert.cpp.

Function Documentation

◆ AllocAndLoadString()

static INT AllocAndLoadString ( _In_ UINT  uID,
_Out_ LPWSTR lpTarget 
)
static

Definition at line 90 of file tracert.cpp.

94{
96 INT Length;
97
100 if (Length++ > 0)
101 {
102 (*lpTarget) = (LPWSTR)LocalAlloc(LMEM_FIXED,
103 Length * sizeof(WCHAR));
104 if ((*lpTarget) != NULL)
105 {
106 INT Ret;
107 if (!(Ret = LoadStringW(hInst, uID, *lpTarget, Length)))
108 {
109 LocalFree((HLOCAL)(*lpTarget));
110 }
111 return Ret;
112 }
113 }
114 return 0;
115}
#define NULL
Definition: types.h:112
HMODULE WINAPI GetModuleHandleW(LPCWSTR lpModuleName)
Definition: loader.c:838
HINSTANCE hInst
Definition: dxdiag.c:13
HLOCAL NTAPI LocalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:1390
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1594
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
static INT LengthOfStrResource(_In_ HINSTANCE hInst, _In_ UINT uID)
Definition: tracert.cpp:60
int32_t INT
Definition: typedefs.h:58
#define LMEM_FIXED
Definition: winbase.h:394
int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPWSTR lpBuffer, _In_ int cchBufferMax)
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184

Referenced by OutputText().

◆ DecodeResponse()

static bool DecodeResponse ( _In_ PVOID  ReplyBuffer,
_In_ PVOID  LastGoodResponse,
_In_ bool  OutputHopAddress,
_Out_ bool GoodResponse,
_Out_ bool FoundTarget 
)
static

Definition at line 321 of file tracert.cpp.

328{
329 ULONG RoundTripTime;
330 PVOID AddressInfo;
331 ULONG Status = GetResponseStats(ReplyBuffer, RoundTripTime, AddressInfo);
332
333 switch (Status)
334 {
335 case IP_SUCCESS:
337 if (RoundTripTime)
338 {
339 OutputText(IDS_HOP_TIME, RoundTripTime);
340 }
341 else
342 {
344 }
345 GoodResponse = true;
346 break;
347
350 FoundTarget = true;
351 PrintHopInfo(AddressInfo);
354 {
356 }
358 {
360 }
361 return true;
362
363 case IP_REQ_TIMED_OUT:
365 break;
366
369 return false;
370
371 default:
373 return false;
374 }
375
376 if (OutputHopAddress)
377 {
378 if (Status == IP_REQ_TIMED_OUT && LastGoodResponse)
379 {
380 Status = GetResponseStats(LastGoodResponse, RoundTripTime, AddressInfo);
381 }
382 if (Status == IP_SUCCESS)
383 {
384 FoundTarget = true;
385 }
387 {
388 PrintHopInfo(AddressInfo);
390 }
391 else if (Status == IP_REQ_TIMED_OUT)
392 {
394 }
395 }
396
397 return true;
398}
#define IDS_DEST_HOST_UNREACHABLE
Definition: resource.h:24
#define IDS_TRANSMIT_FAILED
Definition: resource.h:28
#define IDS_DEST_NET_UNREACHABLE
Definition: resource.h:25
#define IDS_TIMEOUT
Definition: resource.h:14
#define IDS_HOP_TIME
Definition: resource.h:12
#define IDS_HOP_ZERO
Definition: resource.h:13
#define IDS_REQ_TIMED_OUT
Definition: resource.h:17
#define IDS_LINEBREAK
Definition: resource.h:18
#define IDS_HOP_RESPONSE
Definition: resource.h:19
#define IDS_GEN_FAILURE
Definition: resource.h:8
_Must_inspect_result_ _In_ PFLT_PORT _In_ ULONG _Out_writes_bytes_opt_ ReplyLength PVOID ReplyBuffer
Definition: fltkernel.h:1902
Status
Definition: gdiplustypes.h:25
#define IP_DEST_NET_UNREACHABLE
Definition: ipexport.h:115
#define IP_DEST_HOST_UNREACHABLE
Definition: ipexport.h:116
#define IP_GENERAL_FAILURE
Definition: ipexport.h:138
#define IP_REQ_TIMED_OUT
Definition: ipexport.h:123
#define IP_TTL_EXPIRED_TRANSIT
Definition: ipexport.h:126
#define IP_SUCCESS
Definition: ipexport.h:113
static INT OutputText(_In_ UINT uID,...)
Definition: tracert.cpp:119
static bool PrintHopInfo(_In_ PVOID Buffer)
Definition: tracert.cpp:219
static ULONG GetResponseStats(_In_ PVOID ReplyBuffer, _Out_ ULONG &RoundTripTime, _Out_ PVOID &AddressInfo)
Definition: tracert.cpp:287
uint32_t ULONG
Definition: typedefs.h:59

Referenced by RunTraceRoute().

◆ GetResponseStats()

static ULONG GetResponseStats ( _In_ PVOID  ReplyBuffer,
_Out_ ULONG RoundTripTime,
_Out_ PVOID AddressInfo 
)
static

Definition at line 287 of file tracert.cpp.

292{
294
295 if (Info.Family == AF_INET6)
296 {
297 PICMPV6_ECHO_REPLY EchoReplyV6;
298 EchoReplyV6 = (PICMPV6_ECHO_REPLY)ReplyBuffer;
299 Status = EchoReplyV6->Status;
300 RoundTripTime = EchoReplyV6->RoundTripTime;
301 AddressInfo = &EchoReplyV6->Address;
302 }
303 else
304 {
305#ifdef _WIN64
306 PICMP_ECHO_REPLY32 EchoReplyV4;
307 EchoReplyV4 = (PICMP_ECHO_REPLY32)ReplyBuffer;
308#else
309 PICMP_ECHO_REPLY EchoReplyV4;
310 EchoReplyV4 = (PICMP_ECHO_REPLY)ReplyBuffer;
311#endif
312 Status = EchoReplyV4->Status;
313 RoundTripTime = EchoReplyV4->RoundTripTime;
314 AddressInfo = &EchoReplyV4->Address;
315 }
316
317 return Status;
318}
struct icmp_echo_reply * PICMP_ECHO_REPLY
ICMPV6_ECHO_REPLY_LH * PICMPV6_ECHO_REPLY
Definition: ipexport.h:195
IPV6_ADDRESS_EX Address
Definition: ipexport.h:189
unsigned int RoundTripTime
Definition: ipexport.h:191
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:690
#define AF_INET6
Definition: winsock.h:369

Referenced by DecodeResponse().

◆ GetULONG()

static bool GetULONG ( _In_ PCWSTR  String,
_Out_ PULONG  Value 
)
static

Definition at line 163 of file tracert.cpp.

166{
167 PWSTR StopString;
168
169 // Check input arguments
170 if (*String == UNICODE_NULL)
171 return false;
172
173 // Clear errno so we can use its value after
174 // the call to wcstoul to check for errors.
175 errno = 0;
176
177 // Try to convert String to ULONG
178 *Value = wcstoul(String, &StopString, 10);
179 if ((errno != ERANGE) && (errno != 0 || *StopString != UNICODE_NULL))
180 return false;
181 // The conversion was successful
182 return true;
183}
#define ERANGE
Definition: acclib.h:92
_Check_return_ unsigned long __cdecl wcstoul(_In_z_ const wchar_t *_Str, _Out_opt_ _Deref_post_z_ wchar_t **_EndPtr, _In_ int _Radix)
#define UNICODE_NULL
#define errno
Definition: errno.h:18
uint16_t * PWSTR
Definition: typedefs.h:56
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFSTRING String
Definition: wdfdevice.h:2433
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413

Referenced by GetUlongOptionInRange().

◆ GetUlongOptionInRange()

static bool GetUlongOptionInRange ( _In_ int  argc,
_In_ wchar_t argv[],
_Inout_ int i,
_Out_ ULONG Value,
_In_ ULONG  MinimumValue,
_In_ ULONG  MaximumValue 
)
static

Definition at line 571 of file tracert.cpp.

578{
579 ULONG ParsedValue = 0;
580
581 // Check if we have enough values
582 if ((*i + 1) > (argc - 1))
583 {
585 return false;
586 }
587
588 (*i)++;
589
590 // Try to parse and convert the value as ULONG.
591 // Check if ParsedValue is within the specified range.
592 if (!GetULONG(argv[*i], &ParsedValue) ||
593 ((ParsedValue < MinimumValue) || (ParsedValue > MaximumValue)))
594 {
595 (*i)--;
597 return false;
598 }
599
600 *Value = ParsedValue;
601 return true;
602}
static int argc
Definition: ServiceArgs.c:12
#define IDS_BAD_OPTION_VALUE
Definition: resource.h:22
#define IDS_MISSING_OPTION_VALUE
Definition: resource.h:23
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define argv
Definition: mplay32.c:18
static bool GetULONG(_In_ PCWSTR String, _Out_ PULONG Value)
Definition: tracert.cpp:163

Referenced by ParseCmdline().

◆ LengthOfStrResource()

static INT LengthOfStrResource ( _In_ HINSTANCE  hInst,
_In_ UINT  uID 
)
static

Definition at line 60 of file tracert.cpp.

64{
65 HRSRC hrSrc;
66 HGLOBAL hRes;
67 LPWSTR lpName, lpStr;
68
69 if (hInst == NULL) return -1;
70
71 lpName = (LPWSTR)MAKEINTRESOURCE((uID >> 4) + 1);
72
73 if ((hrSrc = FindResourceW(hInst, lpName, (LPWSTR)RT_STRING)) &&
74 (hRes = LoadResource(hInst, hrSrc)) &&
75 (lpStr = (WCHAR*)LockResource(hRes)))
76 {
77 UINT x;
78 uID &= 0xF;
79 for (x = 0; x < uID; x++)
80 {
81 lpStr += (*lpStr) + 1;
82 }
83 return (int)(*lpStr);
84 }
85 return -1;
86}
HRSRC WINAPI FindResourceW(HINSTANCE hModule, LPCWSTR name, LPCWSTR type)
Definition: res.c:176
LPVOID WINAPI LockResource(HGLOBAL handle)
Definition: res.c:550
HGLOBAL WINAPI LoadResource(HINSTANCE hModule, HRSRC hRsrc)
Definition: res.c:532
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
unsigned int UINT
Definition: ndis.h:50
#define MAKEINTRESOURCE(i)
Definition: ntverrsrc.c:25
#define RT_STRING
Definition: pedump.c:368
_In_ LPCSTR lpName
Definition: winbase.h:2820

Referenced by AllocAndLoadString().

◆ OutputText()

static INT OutputText ( _In_ UINT  uID,
  ... 
)
static

Definition at line 119 of file tracert.cpp.

122{
124 DWORD Ret = 0;
125 va_list lArgs;
126
127 if (AllocAndLoadString(uID, &Format) > 0)
128 {
129 va_start(lArgs, uID);
130
133 Format,
134 0,
135 0,
136 (LPWSTR)&Buffer,
137 0,
138 &lArgs);
139 va_end(lArgs);
140
141 if (Ret)
142 {
145 }
147 }
148
149 return Ret;
150}
char * va_list
Definition: acmsvcex.h:78
#define va_end(ap)
Definition: acmsvcex.h:90
#define va_start(ap, A)
Definition: acmsvcex.h:91
Definition: bufpool.h:45
DWORD WINAPI FormatMessageW(DWORD dwFlags, LPCVOID lpSource, DWORD dwMessageId, DWORD dwLanguageId, LPWSTR lpBuffer, DWORD nSize, __ms_va_list *args)
Definition: format_msg.c:583
unsigned long DWORD
Definition: ntddk_ex.h:95
static INT AllocAndLoadString(_In_ UINT uID, _Out_ LPWSTR *lpTarget)
Definition: tracert.cpp:90
#define wprintf(...)
Definition: whoami.c:18
#define FORMAT_MESSAGE_FROM_STRING
Definition: winbase.h:447
#define FORMAT_MESSAGE_ALLOCATE_BUFFER
Definition: winbase.h:445

Referenced by DecodeResponse(), GetUlongOptionInRange(), ParseCmdline(), PrintHopInfo(), RunTraceRoute(), and Usage().

◆ ParseCmdline()

static bool ParseCmdline ( int  argc,
wchar_t argv[] 
)
static

Definition at line 605 of file tracert.cpp.

606{
607 if (argc < 2)
608 {
609 Usage();
610 return false;
611 }
612
613 for (int i = 1; i < argc; i++)
614 {
615 if (argv[i][0] == '-' || argv[i][0] == '/')
616 {
617 switch (argv[i][1])
618 {
619 case 'd':
620 Info.ResolveAddresses = FALSE;
621 break;
622
623 case 'h':
625 argv,
626 &i,
627 &Info.MaxHops,
630 {
631 return false;
632 }
633 break;
634
635 case 'j':
636 printf("-j is not yet implemented.\n");
637 return false;
638
639 case 'w':
641 argv,
642 &i,
643 &Info.Timeout,
646 {
647 return false;
648 }
649 break;
650
651 case '4':
652 Info.Family = AF_INET;
653 break;
654
655 case '6':
656 Info.Family = AF_INET6;
657 break;
658
659 default:
660 {
662 Usage();
663 return false;
664 }
665 }
666 }
667 else
668 {
669 // The host must be the last argument
670 if (i != (argc - 1))
671 {
672 Usage();
673 return false;
674 }
675
676 StringCchCopyW(Info.HostName, NI_MAXHOST, argv[i]);
677 break;
678 }
679 }
680
681 // Check for missing host
682 if (Info.HostName[0] == UNICODE_NULL)
683 {
685 Usage();
686 return false;
687 }
688 return true;
689}
#define IDS_INVALID_OPTION
Definition: resource.h:7
#define IDS_MISSING_TARGET
Definition: resource.h:24
#define FALSE
Definition: types.h:117
#define AF_INET
Definition: tcpip.h:117
#define printf
Definition: freeldr.h:97
STRSAFEAPI StringCchCopyW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:149
#define MAX_HOP_COUNT
Definition: tracert.cpp:37
static bool GetUlongOptionInRange(_In_ int argc, _In_ wchar_t *argv[], _Inout_ int *i, _Out_ ULONG *Value, _In_ ULONG MinimumValue, _In_ ULONG MaximumValue)
Definition: tracert.cpp:571
#define MIN_HOP_COUNT
Definition: tracert.cpp:36
#define MAX_MILLISECONDS
Definition: tracert.cpp:39
#define MIN_MILLISECONDS
Definition: tracert.cpp:38
static VOID Usage()
Definition: tracert.cpp:157
#define NI_MAXHOST
Definition: ws2def.h:359

Referenced by wmain().

◆ PrintHopInfo()

static bool PrintHopInfo ( _In_ PVOID  Buffer)
static

Definition at line 219 of file tracert.cpp.

220{
221 SOCKADDR_IN6 SockAddrIn6 = { 0 };
222 SOCKADDR_IN SockAddrIn = { 0 };
223 PSOCKADDR SockAddr;
225
226 if (Info.Family == AF_INET6)
227 {
229 SockAddrIn6.sin6_family = AF_INET6;
230 CopyMemory(SockAddrIn6.sin6_addr.u.Word, Ipv6Addr->sin6_addr, sizeof(SockAddrIn6.sin6_addr));
231 //SockAddrIn6.sin6_addr = Ipv6Addr->sin6_addr;
232 SockAddr = (PSOCKADDR)&SockAddrIn6;
233 Size = sizeof(SOCKADDR_IN6);
234
235 }
236 else
237 {
239 SockAddrIn.sin_family = AF_INET;
240 SockAddrIn.sin_addr.S_un.S_addr = *Address;
241 SockAddr = (PSOCKADDR)&SockAddrIn;
242 Size = sizeof(SOCKADDR_IN);
243 }
244
245 INT Status;
246 bool Resolved = false;
247 WCHAR HostName[NI_MAXHOST];
248 if (Info.ResolveAddresses)
249 {
250 Status = GetNameInfoW(SockAddr,
251 Size,
252 HostName,
254 NULL,
255 0,
257 if (Status == 0)
258 {
259 Resolved = true;
260 }
261 }
262
263 WCHAR IpAddress[MAX_IPADDRESS];
264 Status = GetNameInfoW(SockAddr,
265 Size,
266 IpAddress,
268 NULL,
269 0,
271 if (Status == 0)
272 {
273 if (Resolved)
274 {
275 OutputText(IDS_HOP_RES_INFO, HostName, IpAddress);
276 }
277 else
278 {
279 OutputText(IDS_HOP_IP_INFO, IpAddress);
280 }
281 }
282
283 return (Status == 0);
284}
INT WSAAPI GetNameInfoW(IN CONST SOCKADDR *pSockaddr, IN socklen_t SockaddrLength, OUT PWCHAR pNodeBuffer, IN DWORD NodeBufferSize, OUT PWCHAR pServiceBuffer, IN DWORD ServiceBufferSize, IN INT Flags)
Definition: addrinfo.c:873
#define IDS_HOP_RES_INFO
Definition: resource.h:15
#define IDS_HOP_IP_INFO
Definition: resource.h:16
struct _IPV6_ADDRESS_EX * PIPV6_ADDRESS_EX
int socklen_t
Definition: tcp.c:35
ULONG IPAddr
Definition: pfhook.h:35
static WCHAR Address[46]
Definition: ping.c:68
USHORT sin6_addr[8]
Definition: ipexport.h:173
USHORT Word[8]
Definition: in6addr.h:6
union in6_addr::@3091 u
ADDRESS_FAMILY sin6_family
Definition: ws2ipdef.h:179
IN6_ADDR sin6_addr
Definition: ws2ipdef.h:182
struct in_addr sin_addr
Definition: winsock.h:512
short sin_family
Definition: winsock.h:510
#define MAX_IPADDRESS
Definition: tracert.cpp:34
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
#define CopyMemory
Definition: winbase.h:1741
struct sockaddr_in SOCKADDR_IN
Definition: winsock.h:487
struct sockaddr * PSOCKADDR
Definition: winsock.h:485
#define NI_NAMEREQD
Definition: ws2def.h:355
#define NI_NUMERICHOST
Definition: ws2def.h:354
SOCKADDR_IN6_LH SOCKADDR_IN6
Definition: ws2ipdef.h:199

Referenced by DecodeResponse().

◆ ResolveTarget()

static bool ResolveTarget ( )
static

Definition at line 186 of file tracert.cpp.

187{
188 ADDRINFOW Hints;
189 ZeroMemory(&Hints, sizeof(Hints));
190 Hints.ai_family = Info.Family;
191 Hints.ai_flags = AI_CANONNAME;
192
193 int Status;
194 Status = GetAddrInfoW(Info.HostName,
195 NULL,
196 &Hints,
197 &Info.Target);
198 if (Status != 0)
199 {
200 return false;
201 }
202
203 Status = GetNameInfoW(Info.Target->ai_addr,
204 Info.Target->ai_addrlen,
205 Info.TargetIP,
207 NULL,
208 0,
210 if (Status != 0)
211 {
212 return false;
213 }
214
215 return true;
216}
INT WSAAPI GetAddrInfoW(IN PCWSTR pszNodeName, IN PCWSTR pszServiceName, IN const ADDRINFOW *ptHints, OUT PADDRINFOW *pptResult)
Definition: addrinfo.c:509
int ai_flags
Definition: ws2def.h:676
int ai_family
Definition: ws2def.h:677
#define ZeroMemory
Definition: winbase.h:1743
#define AI_CANONNAME
Definition: ws2def.h:294

Referenced by RunTraceRoute(), and wmain().

◆ RunTraceRoute()

static bool RunTraceRoute ( )
static

Definition at line 401 of file tracert.cpp.

402{
403 bool Success = false;
404 PVOID ReplyBuffer = NULL, LastGoodResponse = NULL;
405 DWORD ReplySize;
406
408 bool Quit = false;
409 ULONG HopCount = 1;
410 bool FoundTarget = false;
411
413 if (!Success)
414 {
416 goto Cleanup;
417 }
418
420 if (Info.Family == AF_INET6)
421 {
422 ReplySize += sizeof(ICMPV6_ECHO_REPLY);
423 }
424 else
425 {
426#ifdef _WIN64
427 ReplySize += sizeof(ICMP_ECHO_REPLY32);
428#else
429 ReplySize += sizeof(ICMP_ECHO_REPLY);
430#endif
431 }
432
434 if (ReplyBuffer == NULL)
435 {
436 Success = false;
437 goto Cleanup;
438 }
439
440 if (Info.Family == AF_INET6)
441 {
442 Info.hIcmpFile = Icmp6CreateFile();
443 }
444 else
445 {
446 Info.hIcmpFile = IcmpCreateFile();
447 }
448 if (Info.hIcmpFile == INVALID_HANDLE_VALUE)
449 {
450 Success = false;
451 goto Cleanup;
452 }
453
454 OutputText(IDS_TRACE_INFO, Info.HostName, Info.TargetIP, Info.MaxHops);
455
456 IP_OPTION_INFORMATION IpOptionInfo;
457 ZeroMemory(&IpOptionInfo, sizeof(IpOptionInfo));
458
459 while ((HopCount <= Info.MaxHops) && (FoundTarget == false) && (Quit == false))
460 {
461 OutputText(IDS_HOP_COUNT, HopCount);
462
463 if (LastGoodResponse)
464 {
465 HeapFree(heap, 0, LastGoodResponse);
466 LastGoodResponse = NULL;
467 }
468
469 for (int Ping = 1; Ping <= NUM_OF_PINGS; Ping++)
470 {
471 BYTE SendBuffer[PACKET_SIZE];
472 bool GoodResponse = false;
473
474 IpOptionInfo.Ttl = static_cast<UCHAR>(HopCount);
475
476 if (Info.Family == AF_INET6)
477 {
478 struct sockaddr_in6 Source;
479
480 ZeroMemory(&Source, sizeof(Source));
481 Source.sin6_family = AF_INET6;
482
483 (void)Icmp6SendEcho2(Info.hIcmpFile,
484 NULL,
485 NULL,
486 NULL,
487 &Source,
488 (struct sockaddr_in6 *)Info.Target->ai_addr,
489 SendBuffer,
491 &IpOptionInfo,
493 ReplySize,
494 Info.Timeout);
495 }
496 else
497 {
498 (void)IcmpSendEcho2(Info.hIcmpFile,
499 NULL,
500 NULL,
501 NULL,
502 ((PSOCKADDR_IN)Info.Target->ai_addr)->sin_addr.s_addr,
503 SendBuffer,
505 &IpOptionInfo,
507 ReplySize,
508 Info.Timeout);
509 }
510
512 LastGoodResponse,
513 (Ping == NUM_OF_PINGS),
514 GoodResponse,
515 FoundTarget) == false)
516 {
517 Quit = true;
518 break;
519 }
520
521 if (FoundTarget)
522 {
523 Success = true;
524 break;
525 }
526
527 if (GoodResponse)
528 {
529 if (LastGoodResponse)
530 {
531 HeapFree(heap, 0, LastGoodResponse);
532 }
533 LastGoodResponse = HeapAlloc(heap, HEAP_ZERO_MEMORY, ReplySize);
534 if (LastGoodResponse == NULL)
535 {
536 Success = false;
537 goto Cleanup;
538 }
539 CopyMemory(LastGoodResponse, ReplyBuffer, ReplySize);
540 }
541 }
542
543 HopCount++;
544 Sleep(100);
545 }
546
548
549Cleanup:
550 if (ReplyBuffer)
551 {
553 }
554 if (LastGoodResponse)
555 {
556 HeapFree(heap, 0, LastGoodResponse);
557 }
558 if (Info.Target)
559 {
560 FreeAddrInfoW(Info.Target);
561 }
562 if (Info.hIcmpFile)
563 {
564 IcmpCloseHandle(Info.hIcmpFile);
565 }
566
567 return Success;
568}
#define FreeAddrInfoW(a)
Definition: addrinfo.c:21
#define IDS_UNABLE_RESOLVE
Definition: resource.h:7
#define IDS_TRACE_COMPLETE
Definition: resource.h:6
#define IDS_HOP_COUNT
Definition: resource.h:11
#define IDS_TRACE_INFO
Definition: resource.h:5
#define GetProcessHeap()
Definition: compat.h:736
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define HeapAlloc
Definition: compat.h:733
#define HeapFree(x, y, z)
Definition: compat.h:735
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
BOOL WINAPI IcmpCloseHandle(_In_ HANDLE IcmpHandle)
Definition: icmp.c:202
DWORD WINAPI IcmpSendEcho2(_In_ HANDLE IcmpHandle, _In_opt_ HANDLE Event, _In_opt_ PIO_APC_ROUTINE ApcRoutine, _In_opt_ PVOID ApcContext, _In_ IPAddr DestinationAddress, _In_ LPVOID RequestData, _In_ WORD RequestSize, _In_opt_ PIP_OPTION_INFORMATION RequestOptions, _Out_ LPVOID ReplyBuffer, _In_ DWORD ReplySize, _In_ DWORD Timeout)
Definition: icmp.c:285
HANDLE WINAPI Icmp6CreateFile(void)
Definition: icmp.c:15
HANDLE WINAPI IcmpCreateFile(void)
Definition: icmp.c:219
DWORD WINAPI Icmp6SendEcho2(_In_ HANDLE IcmpHandle, _In_opt_ HANDLE Event, _In_opt_ PIO_APC_ROUTINE ApcRoutine, _In_opt_ PVOID ApcContext, _In_ struct sockaddr_in6 *SourceAddress, _In_ struct sockaddr_in6 *DestinationAddress, _In_ LPVOID RequestData, _In_ WORD RequestSize, _In_ PIP_OPTION_INFORMATION RequestOptions, _Out_ LPVOID ReplyBuffer, _In_ DWORD ReplySize, _In_ DWORD Timeout)
Definition: icmp.c:77
static const WCHAR Cleanup[]
Definition: register.c:80
@ Success
Definition: eventcreate.c:712
ICMPV6_ECHO_REPLY_LH ICMPV6_ECHO_REPLY
Definition: ipexport.h:194
struct icmp_echo_reply ICMP_ECHO_REPLY
_In_ UINT _In_ UINT _In_ PNDIS_PACKET Source
Definition: ndis.h:3169
unsigned short USHORT
Definition: pedump.c:61
static void Ping(void)
Definition: ping.c:419
static HANDLE heap
Definition: heap.c:65
unsigned char Ttl
Definition: ipexport.h:33
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
#define NUM_OF_PINGS
Definition: tracert.cpp:35
#define SIZEOF_ICMP_ERROR
Definition: tracert.cpp:31
static bool DecodeResponse(_In_ PVOID ReplyBuffer, _In_ PVOID LastGoodResponse, _In_ bool OutputHopAddress, _Out_ bool &GoodResponse, _Out_ bool &FoundTarget)
Definition: tracert.cpp:321
#define SIZEOF_IO_STATUS_BLOCK
Definition: tracert.cpp:32
static bool ResolveTarget()
Definition: tracert.cpp:186
#define PACKET_SIZE
Definition: tracert.cpp:33
unsigned char UCHAR
Definition: xmlstorage.h:181
unsigned char BYTE
Definition: xxhash.c:193

Referenced by wmain().

◆ Usage()

static VOID Usage ( void  )
static

Definition at line 157 of file tracert.cpp.

158{
160}
#define IDS_USAGE
Definition: resource.h:3

Referenced by ParseCmdline().

◆ wmain()

EXTERN_C int wmain ( int  argc,
wchar_t argv[] 
)

Definition at line 692 of file tracert.cpp.

693{
694#ifdef USE_CONUTILS
695 /* Initialize the Console Standard Streams */
697#endif
698
699 Info.ResolveAddresses = true;
700 Info.MaxHops = 30;
701 Info.Timeout = 4000;
702 Info.Family = AF_UNSPEC;
703
704 if (!ParseCmdline(argc, argv))
705 {
706 return 1;
707 }
708
709 WSADATA WsaData;
710 if (WSAStartup(MAKEWORD(2, 2), &WsaData))
711 {
712 return 1;
713 }
714
715 bool Success;
717
718 WSACleanup();
719
720 return Success ? 0 : 1;
721}
#define ConInitStdStreams()
Definition: fc.c:13
INT WINAPI WSAStartup(IN WORD wVersionRequested, OUT LPWSADATA lpWSAData)
Definition: startup.c:113
static bool RunTraceRoute()
Definition: tracert.cpp:401
static bool ParseCmdline(int argc, wchar_t *argv[])
Definition: tracert.cpp:605
#define MAKEWORD(a, b)
Definition: typedefs.h:248
int PASCAL FAR WSACleanup(void)
Definition: startup.c:60
#define AF_UNSPEC
Definition: winsock.h:344

Variable Documentation

◆ Info