ReactOS  0.4.15-dev-5126-g3bb451b
tracert.cpp File Reference
#include <winsock2.h>
#include <Windows.h>
#include <ws2tcpip.h>
#include <iphlpapi.h>
#include <icmpapi.h>
#include <strsafe.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
 

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 ULONG GetULONG (_In_z_ LPWSTR String)
 
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 ParseCmdline (int argc, wchar_t *argv[])
 
EXTERN_C int wmain (int argc, wchar_t *argv[])
 

Variables

struct TraceInfo Info = { 0 }
 

Macro Definition Documentation

◆ MAX_IPADDRESS

#define MAX_IPADDRESS   32

Definition at line 32 of file tracert.cpp.

◆ NUM_OF_PINGS

#define NUM_OF_PINGS   3

Definition at line 33 of file tracert.cpp.

◆ PACKET_SIZE

#define PACKET_SIZE   32

Definition at line 31 of file tracert.cpp.

◆ SIZEOF_ICMP_ERROR

#define SIZEOF_ICMP_ERROR   8

Definition at line 29 of file tracert.cpp.

◆ SIZEOF_IO_STATUS_BLOCK

#define SIZEOF_IO_STATUS_BLOCK   8

Definition at line 30 of file tracert.cpp.

Function Documentation

◆ AllocAndLoadString()

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

Definition at line 84 of file tracert.cpp.

88 {
89  HMODULE hInst;
90  INT Length;
91 
94  if (Length++ > 0)
95  {
96  (*lpTarget) = (LPWSTR)LocalAlloc(LMEM_FIXED,
97  Length * sizeof(WCHAR));
98  if ((*lpTarget) != NULL)
99  {
100  INT Ret;
101  if (!(Ret = LoadStringW(hInst, uID, *lpTarget, Length)))
102  {
103  LocalFree((HLOCAL)(*lpTarget));
104  }
105  return Ret;
106  }
107  }
108  return 0;
109 }
static INT LengthOfStrResource(_In_ HINSTANCE hInst, _In_ UINT uID)
Definition: tracert.cpp:54
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPWSTR lpBuffer, _In_ int cchBufferMax)
int32_t INT
Definition: typedefs.h:58
#define LMEM_FIXED
Definition: winbase.h:365
__wchar_t WCHAR
Definition: xmlstorage.h:180
HINSTANCE hInst
Definition: dxdiag.c:13
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1577
#define NULL
Definition: types.h:112
HMODULE WINAPI GetModuleHandleW(LPCWSTR lpModuleName)
Definition: loader.c:838
HLOCAL NTAPI LocalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:1373
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 311 of file tracert.cpp.

318 {
319  ULONG RoundTripTime;
320  PVOID AddressInfo;
321  ULONG Status = GetResponseStats(ReplyBuffer, RoundTripTime, AddressInfo);
322 
323  switch (Status)
324  {
325  case IP_SUCCESS:
327  if (RoundTripTime)
328  {
329  OutputText(IDS_HOP_TIME, RoundTripTime);
330  }
331  else
332  {
334  }
335  GoodResponse = true;
336  break;
337 
340  FoundTarget = true;
341  PrintHopInfo(AddressInfo);
344  {
346  }
347  else if (Status == IP_DEST_NET_UNREACHABLE)
348  {
350  }
351  return true;
352 
353  case IP_REQ_TIMED_OUT:
355  break;
356 
357  case IP_GENERAL_FAILURE:
359  return false;
360 
361  default:
363  return false;
364  }
365 
366  if (OutputHopAddress)
367  {
368  if (Status == IP_REQ_TIMED_OUT && LastGoodResponse)
369  {
370  Status = GetResponseStats(LastGoodResponse, RoundTripTime, AddressInfo);
371  }
372  if (Status == IP_SUCCESS)
373  {
374  FoundTarget = true;
375  }
377  {
378  PrintHopInfo(AddressInfo);
380  }
381  else if (Status == IP_REQ_TIMED_OUT)
382  {
384  }
385  }
386 
387  return true;
388 }
#define IDS_TIMEOUT
Definition: resource.h:14
#define IDS_DEST_NET_UNREACHABLE
Definition: resource.h:25
#define IP_TTL_EXPIRED_TRANSIT
Definition: ipexport.h:126
#define IDS_LINEBREAK
Definition: resource.h:18
static INT OutputText(_In_ UINT uID,...)
Definition: tracert.cpp:113
#define IDS_HOP_TIME
Definition: resource.h:12
#define IDS_DEST_HOST_UNREACHABLE
Definition: resource.h:24
#define IDS_HOP_RESPONSE
Definition: resource.h:19
Status
Definition: gdiplustypes.h:24
#define IP_GENERAL_FAILURE
Definition: ipexport.h:138
#define IP_REQ_TIMED_OUT
Definition: ipexport.h:123
#define IP_DEST_NET_UNREACHABLE
Definition: ipexport.h:115
_Must_inspect_result_ _In_ PFLT_PORT _In_ ULONG _Out_writes_bytes_opt_ ReplyLength PVOID ReplyBuffer
Definition: fltkernel.h:1902
#define IDS_TRANSMIT_FAILED
Definition: resource.h:28
#define IDS_HOP_ZERO
Definition: resource.h:13
#define IDS_GEN_FAILURE
Definition: resource.h:8
static ULONG GetResponseStats(_In_ PVOID ReplyBuffer, _Out_ ULONG &RoundTripTime, _Out_ PVOID &AddressInfo)
Definition: tracert.cpp:277
#define IP_SUCCESS
Definition: ipexport.h:113
unsigned int ULONG
Definition: retypes.h:1
#define IDS_REQ_TIMED_OUT
Definition: resource.h:17
#define IP_DEST_HOST_UNREACHABLE
Definition: ipexport.h:116
static bool PrintHopInfo(_In_ PVOID Buffer)
Definition: tracert.cpp:209

Referenced by RunTraceRoute().

◆ GetResponseStats()

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

Definition at line 277 of file tracert.cpp.

282 {
283  ULONG Status;
284 
285  if (Info.Family == AF_INET6)
286  {
287  PICMPV6_ECHO_REPLY EchoReplyV6;
288  EchoReplyV6 = (PICMPV6_ECHO_REPLY)ReplyBuffer;
289  Status = EchoReplyV6->Status;
290  RoundTripTime = EchoReplyV6->RoundTripTime;
291  AddressInfo = &EchoReplyV6->Address;
292  }
293  else
294  {
295 #ifdef _WIN64
296  PICMP_ECHO_REPLY32 EchoReplyV4;
297  EchoReplyV4 = (PICMP_ECHO_REPLY32)ReplyBuffer;
298 #else
299  PICMP_ECHO_REPLY EchoReplyV4;
300  EchoReplyV4 = (PICMP_ECHO_REPLY)ReplyBuffer;
301 #endif
302  Status = EchoReplyV4->Status;
303  RoundTripTime = EchoReplyV4->RoundTripTime;
304  AddressInfo = &EchoReplyV4->Address;
305  }
306 
307  return Status;
308 }
UINT32 RoundTripTime
Definition: ipexport.h:86
struct icmp_echo_reply * PICMP_ECHO_REPLY
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:683
IPAddr Address
Definition: ipexport.h:84
#define AF_INET6
Definition: winsock.h:369
Status
Definition: gdiplustypes.h:24
ICMPV6_ECHO_REPLY_LH * PICMPV6_ECHO_REPLY
Definition: ipexport.h:195
_Must_inspect_result_ _In_ PFLT_PORT _In_ ULONG _Out_writes_bytes_opt_ ReplyLength PVOID ReplyBuffer
Definition: fltkernel.h:1902
IPV6_ADDRESS_EX Address
Definition: ipexport.h:189
unsigned int RoundTripTime
Definition: ipexport.h:191
UINT32 Status
Definition: ipexport.h:85
unsigned int ULONG
Definition: retypes.h:1

Referenced by DecodeResponse().

◆ GetULONG()

static ULONG GetULONG ( _In_z_ LPWSTR  String)
static

Definition at line 157 of file tracert.cpp.

160 {
161  ULONG Length;
162  Length = wcslen(String);
163 
164  ULONG i = 0;
165  while ((i < Length) && ((String[i] < L'0') || (String[i] > L'9'))) i++;
166  if ((i >= Length) || ((String[i] < L'0') || (String[i] > L'9')))
167  {
168  return (ULONG)-1;
169  }
170 
171  LPWSTR StopString;
172  return wcstoul(&String[i], &StopString, 10);
173 }
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
_Check_return_ unsigned long __cdecl wcstoul(_In_z_ const wchar_t *_Str, _Out_opt_ _Deref_post_z_ wchar_t **_EndPtr, _In_ int _Radix)
#define L(x)
Definition: ntvdm.h:50
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFSTRING String
Definition: wdfdevice.h:2430
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
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
unsigned int ULONG
Definition: retypes.h:1
WCHAR * LPWSTR
Definition: xmlstorage.h:184

Referenced by ParseCmdline().

◆ LengthOfStrResource()

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

Definition at line 54 of file tracert.cpp.

58 {
59  HRSRC hrSrc;
60  HGLOBAL hRes;
61  LPWSTR lpName, lpStr;
62 
63  if (hInst == NULL) return -1;
64 
65  lpName = (LPWSTR)MAKEINTRESOURCE((uID >> 4) + 1);
66 
67  if ((hrSrc = FindResourceW(hInst, lpName, (LPWSTR)RT_STRING)) &&
68  (hRes = LoadResource(hInst, hrSrc)) &&
69  (lpStr = (WCHAR*)LockResource(hRes)))
70  {
71  UINT x;
72  uID &= 0xF;
73  for (x = 0; x < uID; x++)
74  {
75  lpStr += (*lpStr) + 1;
76  }
77  return (int)(*lpStr);
78  }
79  return -1;
80 }
#define MAKEINTRESOURCE
Definition: winuser.h:591
_In_ LPCSTR lpName
Definition: winbase.h:2773
LPVOID WINAPI LockResource(HGLOBAL handle)
Definition: res.c:550
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
HRSRC WINAPI FindResourceW(HINSTANCE hModule, LPCWSTR name, LPCWSTR type)
Definition: res.c:176
HGLOBAL WINAPI LoadResource(HINSTANCE hModule, HRSRC hRsrc)
Definition: res.c:532
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define RT_STRING
Definition: pedump.c:368
HINSTANCE hInst
Definition: dxdiag.c:13
unsigned int UINT
Definition: ndis.h:50
#define NULL
Definition: types.h:112
WCHAR * LPWSTR
Definition: xmlstorage.h:184

Referenced by AllocAndLoadString().

◆ OutputText()

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

Definition at line 113 of file tracert.cpp.

116 {
117  LPWSTR Format;
118  DWORD Ret = 0;
119  va_list lArgs;
120 
121  if (AllocAndLoadString(uID, &Format) > 0)
122  {
123  va_start(lArgs, uID);
124 
125  LPWSTR Buffer;
127  Format,
128  0,
129  0,
130  (LPWSTR)&Buffer,
131  0,
132  &lArgs);
133  va_end(lArgs);
134 
135  if (Ret)
136  {
137  wprintf(Buffer);
138  LocalFree(Buffer);
139  }
141  }
142 
143  return Ret;
144 }
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
#define FORMAT_MESSAGE_FROM_STRING
Definition: winbase.h:418
#define wprintf(...)
Definition: whoami.c:18
DWORD WINAPI FormatMessageW(DWORD dwFlags, LPCVOID lpSource, DWORD dwMessageId, DWORD dwLanguageId, LPWSTR lpBuffer, DWORD nSize, __ms_va_list *args)
Definition: format_msg.c:583
#define va_end(ap)
Definition: acmsvcex.h:90
#define FORMAT_MESSAGE_ALLOCATE_BUFFER
Definition: winbase.h:416
char * va_list
Definition: acmsvcex.h:78
Definition: bufpool.h:45
static INT AllocAndLoadString(_In_ UINT uID, _Out_ LPWSTR *lpTarget)
Definition: tracert.cpp:84
unsigned long DWORD
Definition: ntddk_ex.h:95
va_start(ap, x)
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1577
WCHAR * LPWSTR
Definition: xmlstorage.h:184
ACPI_BUFFER *RetBuffer ACPI_BUFFER *RetBuffer char ACPI_WALK_RESOURCE_CALLBACK void *Context ACPI_BUFFER *RetBuffer UINT16 ACPI_RESOURCE **ResourcePtr ACPI_GENERIC_ADDRESS *Reg UINT32 *ReturnValue UINT8 UINT8 *Slp_TypB ACPI_PHYSICAL_ADDRESS PhysicalAddress64 UINT32 UINT32 *TimeElapsed UINT32 ACPI_STATUS const char * Format
Definition: acpixf.h:1216

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

◆ ParseCmdline()

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

Definition at line 561 of file tracert.cpp.

562 {
563  if (argc < 2)
564  {
565  Usage();
566  return false;
567  }
568 
569  for (int i = 1; i < argc; i++)
570  {
571  if (argv[i][0] == '-')
572  {
573  switch (argv[i][1])
574  {
575  case 'd':
576  Info.ResolveAddresses = FALSE;
577  break;
578 
579  case 'h':
580  Info.MaxHops = GetULONG(argv[++i]);
581  break;
582 
583  case 'j':
584  printf("-j is not yet implemented.\n");
585  return false;
586 
587  case 'w':
588  Info.Timeout = GetULONG(argv[++i]);
589  break;
590 
591  case '4':
592  Info.Family = AF_INET;
593  break;
594 
595  case '6':
596  Info.Family = AF_INET6;
597  break;
598 
599  default:
600  {
602  Usage();
603  return false;
604  }
605  }
606  }
607  else
608  {
609  StringCchCopyW(Info.HostName, NI_MAXHOST, argv[i]);
610  break;
611  }
612  }
613 
614  return true;
615 }
static int argc
Definition: ServiceArgs.c:12
#define argv
Definition: mplay32.c:18
#define IDS_INVALID_OPTION
Definition: resource.h:7
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:683
#define FALSE
Definition: types.h:117
STRSAFEAPI StringCchCopyW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:149
#define AF_INET6
Definition: winsock.h:369
static INT OutputText(_In_ UINT uID,...)
Definition: tracert.cpp:113
#define printf
Definition: freeldr.h:94
#define NI_MAXHOST
Definition: ws2def.h:359
static VOID Usage()
Definition: tracert.cpp:151
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 AF_INET
Definition: tcpip.h:117
static ULONG GetULONG(_In_z_ LPWSTR String)
Definition: tracert.cpp:157

Referenced by wmain().

◆ PrintHopInfo()

static bool PrintHopInfo ( _In_ PVOID  Buffer)
static

Definition at line 209 of file tracert.cpp.

210 {
211  SOCKADDR_IN6 SockAddrIn6 = { 0 };
212  SOCKADDR_IN SockAddrIn = { 0 };
213  PSOCKADDR SockAddr;
214  socklen_t Size;
215 
216  if (Info.Family == AF_INET6)
217  {
219  SockAddrIn6.sin6_family = AF_INET6;
220  CopyMemory(SockAddrIn6.sin6_addr.u.Word, Ipv6Addr->sin6_addr, sizeof(SockAddrIn6.sin6_addr));
221  //SockAddrIn6.sin6_addr = Ipv6Addr->sin6_addr;
222  SockAddr = (PSOCKADDR)&SockAddrIn6;
223  Size = sizeof(SOCKADDR_IN6);
224 
225  }
226  else
227  {
228  IPAddr *Address = (IPAddr *)Buffer;
229  SockAddrIn.sin_family = AF_INET;
230  SockAddrIn.sin_addr.S_un.S_addr = *Address;
231  SockAddr = (PSOCKADDR)&SockAddrIn;
232  Size = sizeof(SOCKADDR_IN);
233  }
234 
235  INT Status;
236  bool Resolved = false;
237  WCHAR HostName[NI_MAXHOST];
238  if (Info.ResolveAddresses)
239  {
240  Status = GetNameInfoW(SockAddr,
241  Size,
242  HostName,
243  NI_MAXHOST,
244  NULL,
245  0,
246  NI_NAMEREQD);
247  if (Status == 0)
248  {
249  Resolved = true;
250  }
251  }
252 
253  WCHAR IpAddress[MAX_IPADDRESS];
254  Status = GetNameInfoW(SockAddr,
255  Size,
256  IpAddress,
258  NULL,
259  0,
261  if (Status == 0)
262  {
263  if (Resolved)
264  {
265  OutputText(IDS_HOP_RES_INFO, HostName, IpAddress);
266  }
267  else
268  {
269  OutputText(IDS_HOP_IP_INFO, IpAddress);
270  }
271  }
272 
273  return (Status == 0);
274 }
#define NI_NAMEREQD
Definition: ws2def.h:355
struct _IPV6_ADDRESS_EX * PIPV6_ADDRESS_EX
#define NI_NUMERICHOST
Definition: ws2def.h:354
ADDRESS_FAMILY sin6_family
Definition: ws2ipdef.h:179
#define IDS_HOP_IP_INFO
Definition: resource.h:16
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
#define MAX_IPADDRESS
Definition: tracert.cpp:32
struct sockaddr * PSOCKADDR
Definition: winsock.h:485
int32_t INT
Definition: typedefs.h:58
USHORT Word[8]
Definition: in6addr.h:6
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:683
static WCHAR Address[46]
Definition: ping.c:68
#define AF_INET6
Definition: winsock.h:369
Definition: bufpool.h:45
ULONG IPAddr
Definition: pfhook.h:35
static INT OutputText(_In_ UINT uID,...)
Definition: tracert.cpp:113
Status
Definition: gdiplustypes.h:24
IN6_ADDR sin6_addr
Definition: ws2ipdef.h:182
union in6_addr::@2954 u
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define CopyMemory
Definition: winbase.h:1665
int socklen_t
Definition: tcp.c:35
#define NI_MAXHOST
Definition: ws2def.h:359
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
struct in_addr sin_addr
Definition: winsock.h:512
struct sockaddr_in SOCKADDR_IN
Definition: winsock.h:487
#define NULL
Definition: types.h:112
SOCKADDR_IN6_LH SOCKADDR_IN6
Definition: ws2ipdef.h:199
#define AF_INET
Definition: tcpip.h:117
#define IDS_HOP_RES_INFO
Definition: resource.h:15
short sin_family
Definition: winsock.h:510
USHORT sin6_addr[8]
Definition: ipexport.h:173

Referenced by DecodeResponse().

◆ ResolveTarget()

static bool ResolveTarget ( )
static

Definition at line 176 of file tracert.cpp.

177 {
178  ADDRINFOW Hints;
179  ZeroMemory(&Hints, sizeof(Hints));
180  Hints.ai_family = Info.Family;
181  Hints.ai_flags = AI_CANONNAME;
182 
183  int Status;
184  Status = GetAddrInfoW(Info.HostName,
185  NULL,
186  &Hints,
187  &Info.Target);
188  if (Status != 0)
189  {
190  return false;
191  }
192 
193  Status = GetNameInfoW(Info.Target->ai_addr,
194  Info.Target->ai_addrlen,
195  Info.TargetIP,
197  NULL,
198  0,
200  if (Status != 0)
201  {
202  return false;
203  }
204 
205  return true;
206 }
#define NI_NUMERICHOST
Definition: ws2def.h:354
#define AI_CANONNAME
Definition: ws2def.h:294
#define ZeroMemory
Definition: winbase.h:1667
#define MAX_IPADDRESS
Definition: tracert.cpp:32
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:683
INT WSAAPI GetAddrInfoW(IN PCWSTR pszNodeName, IN PCWSTR pszServiceName, IN const ADDRINFOW *ptHints, OUT PADDRINFOW *pptResult)
Definition: addrinfo.c:509
int ai_family
Definition: ws2def.h:677
Status
Definition: gdiplustypes.h:24
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
int ai_flags
Definition: ws2def.h:676
#define NULL
Definition: types.h:112

Referenced by RunTraceRoute().

◆ RunTraceRoute()

static bool RunTraceRoute ( )
static

Definition at line 391 of file tracert.cpp.

392 {
393  bool Success = false;
394  PVOID ReplyBuffer = NULL, LastGoodResponse = NULL;
395  DWORD ReplySize;
396 
397  HANDLE heap = GetProcessHeap();
398  bool Quit = false;
399  ULONG HopCount = 1;
400  bool FoundTarget = false;
401 
403  if (!Success)
404  {
406  goto Cleanup;
407  }
408 
410  if (Info.Family == AF_INET6)
411  {
412  ReplySize += sizeof(ICMPV6_ECHO_REPLY);
413  }
414  else
415  {
416 #ifdef _WIN64
417  ReplySize += sizeof(ICMP_ECHO_REPLY32);
418 #else
419  ReplySize += sizeof(ICMP_ECHO_REPLY);
420 #endif
421  }
422 
423  ReplyBuffer = HeapAlloc(heap, HEAP_ZERO_MEMORY, ReplySize);
424  if (ReplyBuffer == NULL)
425  {
426  Success = false;
427  goto Cleanup;
428  }
429 
430  if (Info.Family == AF_INET6)
431  {
432  Info.hIcmpFile = Icmp6CreateFile();
433  }
434  else
435  {
436  Info.hIcmpFile = IcmpCreateFile();
437  }
438  if (Info.hIcmpFile == INVALID_HANDLE_VALUE)
439  {
440  Success = false;
441  goto Cleanup;
442  }
443 
444  OutputText(IDS_TRACE_INFO, Info.HostName, Info.TargetIP, Info.MaxHops);
445 
446  IP_OPTION_INFORMATION IpOptionInfo;
447  ZeroMemory(&IpOptionInfo, sizeof(IpOptionInfo));
448 
449  while ((HopCount <= Info.MaxHops) && (FoundTarget == false) && (Quit == false))
450  {
451  OutputText(IDS_HOP_COUNT, HopCount);
452 
453  if (LastGoodResponse)
454  {
455  HeapFree(heap, 0, LastGoodResponse);
456  LastGoodResponse = NULL;
457  }
458 
459  for (int Ping = 1; Ping <= NUM_OF_PINGS; Ping++)
460  {
461  BYTE SendBuffer[PACKET_SIZE];
462  bool GoodResponse = false;
463 
464  IpOptionInfo.Ttl = static_cast<UCHAR>(HopCount);
465 
466  if (Info.Family == AF_INET6)
467  {
468  struct sockaddr_in6 Source;
469 
470  ZeroMemory(&Source, sizeof(Source));
471  Source.sin6_family = AF_INET6;
472 
473  (void)Icmp6SendEcho2(Info.hIcmpFile,
474  NULL,
475  NULL,
476  NULL,
477  &Source,
478  (struct sockaddr_in6 *)Info.Target->ai_addr,
479  SendBuffer,
481  &IpOptionInfo,
482  ReplyBuffer,
483  ReplySize,
484  Info.Timeout);
485  }
486  else
487  {
488  (void)IcmpSendEcho2(Info.hIcmpFile,
489  NULL,
490  NULL,
491  NULL,
492  ((PSOCKADDR_IN)Info.Target->ai_addr)->sin_addr.s_addr,
493  SendBuffer,
495  &IpOptionInfo,
496  ReplyBuffer,
497  ReplySize,
498  Info.Timeout);
499  }
500 
502  LastGoodResponse,
503  (Ping == NUM_OF_PINGS),
504  GoodResponse,
505  FoundTarget) == false)
506  {
507  Quit = true;
508  break;
509  }
510 
511  if (FoundTarget)
512  {
513  Success = true;
514  break;
515  }
516 
517  if (GoodResponse)
518  {
519  if (LastGoodResponse)
520  {
521  HeapFree(heap, 0, LastGoodResponse);
522  }
523  LastGoodResponse = HeapAlloc(heap, HEAP_ZERO_MEMORY, ReplySize);
524  if (LastGoodResponse == NULL)
525  {
526  Success = false;
527  goto Cleanup;
528  }
529  CopyMemory(LastGoodResponse, ReplyBuffer, ReplySize);
530  }
531  }
532 
533  HopCount++;
534  Sleep(100);
535  }
536 
538 
539 Cleanup:
540  if (ReplyBuffer)
541  {
542  HeapFree(heap, 0, ReplyBuffer);
543  }
544  if (LastGoodResponse)
545  {
546  HeapFree(heap, 0, LastGoodResponse);
547  }
548  if (Info.Target)
549  {
550  FreeAddrInfoW(Info.Target);
551  }
552  if (Info.hIcmpFile)
553  {
554  IcmpCloseHandle(Info.hIcmpFile);
555  }
556 
557  return Success;
558 }
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
BOOL WINAPI IcmpCloseHandle(_In_ HANDLE IcmpHandle)
Definition: icmp.c:202
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
#define NUM_OF_PINGS
Definition: tracert.cpp:33
#define INVALID_HANDLE_VALUE
Definition: compat.h:590
#define ZeroMemory
Definition: winbase.h:1667
#define SIZEOF_IO_STATUS_BLOCK
Definition: tracert.cpp:30
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:683
#define IDS_HOP_COUNT
Definition: resource.h:11
static void Ping(void)
Definition: ping.c:419
#define AF_INET6
Definition: winsock.h:369
static INT OutputText(_In_ UINT uID,...)
Definition: tracert.cpp:113
#define GetProcessHeap()
Definition: compat.h:595
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
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 bool ResolveTarget()
Definition: tracert.cpp:176
#define CopyMemory
Definition: winbase.h:1665
unsigned long DWORD
Definition: ntddk_ex.h:95
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
unsigned char Ttl
Definition: ipexport.h:33
ICMPV6_ECHO_REPLY_LH ICMPV6_ECHO_REPLY
Definition: ipexport.h:194
_Must_inspect_result_ _In_ PFLT_PORT _In_ ULONG _Out_writes_bytes_opt_ ReplyLength PVOID ReplyBuffer
Definition: fltkernel.h:1902
static const WCHAR Cleanup[]
Definition: register.c:80
unsigned char BYTE
Definition: xxhash.c:193
#define SIZEOF_ICMP_ERROR
Definition: tracert.cpp:29
#define IDS_UNABLE_RESOLVE
Definition: resource.h:7
unsigned short USHORT
Definition: pedump.c:61
HANDLE WINAPI Icmp6CreateFile(void)
Definition: icmp.c:15
#define NULL
Definition: types.h:112
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
WINSOCK_API_LINKAGE VOID WSAAPI FreeAddrInfoW(_In_opt_ PADDRINFOW pAddrInfo)
static bool DecodeResponse(_In_ PVOID ReplyBuffer, _In_ PVOID LastGoodResponse, _In_ bool OutputHopAddress, _Out_ bool &GoodResponse, _Out_ bool &FoundTarget)
Definition: tracert.cpp:311
#define PACKET_SIZE
Definition: tracert.cpp:31
unsigned int ULONG
Definition: retypes.h:1
#define IDS_TRACE_COMPLETE
Definition: resource.h:6
_In_ UINT _In_ UINT _In_ PNDIS_PACKET Source
Definition: ndis.h:3167
HANDLE WINAPI IcmpCreateFile(void)
Definition: icmp.c:219
#define IDS_TRACE_INFO
Definition: resource.h:5
struct icmp_echo_reply ICMP_ECHO_REPLY
#define HeapFree(x, y, z)
Definition: compat.h:594

Referenced by wmain().

◆ Usage()

static VOID Usage ( void  )
static

Definition at line 151 of file tracert.cpp.

152 {
154 }
#define IDS_USAGE
Definition: resource.h:3
static INT OutputText(_In_ UINT uID,...)
Definition: tracert.cpp:113

Referenced by ParseCmdline().

◆ wmain()

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

Definition at line 618 of file tracert.cpp.

619 {
620 #ifdef USE_CONUTILS
621  /* Initialize the Console Standard Streams */
623 #endif
624 
625  Info.ResolveAddresses = true;
626  Info.MaxHops = 30;
627  Info.Timeout = 4000;
628  Info.Family = AF_UNSPEC;
629 
630  if (!ParseCmdline(argc, argv))
631  {
632  return 1;
633  }
634 
635  WSADATA WsaData;
636  if (WSAStartup(MAKEWORD(2, 2), &WsaData))
637  {
638  return 1;
639  }
640 
641  bool Success;
643 
644  WSACleanup();
645 
646  return Success ? 0 : 1;
647 }
static int argc
Definition: ServiceArgs.c:12
#define MAKEWORD(a, b)
Definition: typedefs.h:248
static bool RunTraceRoute()
Definition: tracert.cpp:391
INT WSAAPI WSACleanup(VOID)
Definition: startup.c:60
#define argv
Definition: mplay32.c:18
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:683
INT WINAPI WSAStartup(IN WORD wVersionRequested, OUT LPWSADATA lpWSAData)
Definition: startup.c:113
#define AF_UNSPEC
Definition: winsock.h:344
#define ConInitStdStreams()
Definition: fc.c:13
static bool ParseCmdline(int argc, wchar_t *argv[])
Definition: tracert.cpp:561

Variable Documentation

◆ Info