ReactOS 0.4.15-dev-7788-g1ad9096
arping.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS ping utility
4 * FILE: applications/cmdutils/arping/arping.c
5 * PURPOSE: Network test utility
6 * PROGRAMMERS: Pierre Schweitzer <pierre@reactos.org>
7 */
8
9#define WIN32_NO_STATUS
10#include <stdarg.h>
11#include <windef.h>
12#include <winbase.h>
13#include <winuser.h>
14#include <winnls.h>
15#include <wincon.h>
16#define _INC_WINDOWS
17#include <ws2tcpip.h>
18#include <iphlpapi.h>
19#include <ws2def.h>
20#include <stdio.h>
21#include <stdlib.h>
22
23#include "resource.h"
24
41
42void FormatOutput(UINT uID, ...)
43{
45
46 WCHAR Buf[1024];
47 CHAR AnsiBuf[1024];
48 LPWSTR pBuf = Buf;
49 PCHAR pAnsiBuf = AnsiBuf;
50 WCHAR Format[1024];
51 DWORD written;
53 int AnsiLength;
54
56 Format, sizeof(Format) / sizeof(WCHAR)))
57 {
58 return;
59 }
60
61 va_start(valist, uID);
63 sizeof(Buf) / sizeof(WCHAR), &valist);
65
66 if(!DataLength)
67 {
69 {
70 return;
71 }
72
73 va_start(valist, uID);
76 Format, 0, 0, (LPWSTR)&pBuf, 0, &valist);
78 }
79
80 if(!DataLength)
81 {
82 return;
83 }
84
86 {
87 /* Is a console or a printer */
88 WriteConsole(hStdOutput, pBuf, DataLength, &written, NULL);
89 }
90 else
91 {
92 /* Is a pipe, socket, file or other */
93 AnsiLength = WideCharToMultiByte(CP_ACP, 0, pBuf, DataLength,\
94 NULL, 0, NULL, NULL);
95
96 if(AnsiLength >= sizeof(AnsiBuf))
97 pAnsiBuf = (PCHAR)HeapAlloc(GetProcessHeap(), 0, AnsiLength);
98
99 AnsiLength = WideCharToMultiByte(CP_OEMCP, 0, pBuf, DataLength,\
100 pAnsiBuf, AnsiLength, " ", NULL);
101
102 WriteFile(hStdOutput, pAnsiBuf, AnsiLength, &written, NULL);
103
104 if(pAnsiBuf != AnsiBuf)
105 HeapFree(NULL, 0, pAnsiBuf);
106 }
107
108 if(pBuf != Buf)
109 LocalFree(pBuf);
110}
111
113{
115}
116
118{
119 INT i;
120
121 if (argc < 3)
122 {
123 Usage();
124 return FALSE;
125 }
126
127 for (i = 1; i < argc; i++)
128 {
129 if (argv[i][0] == L'-' || argv[i][0] == L'/')
130 {
131 switch (argv[i][1])
132 {
133 case L't': NeverStop = TRUE; break;
134 case L'n':
135 if (i + 1 < argc)
136 {
137 PingCount = wcstoul(argv[++i], NULL, 0);
138
139 if (PingCount == 0)
140 {
142 return FALSE;
143 }
144 }
145 else
146 {
148 return FALSE;
149 }
150 break;
151
152 case L's':
153 if (SourceName[0] != 0)
154 {
156 return FALSE;
157 }
158
159 if (i + 1 < argc)
160 {
161 wcscpy(SourceName, argv[++i]);
162 }
163 else
164 {
166 return FALSE;
167 }
168 break;
169
170 case '?':
171 Usage();
172 return FALSE;
173
174 default:
176 return FALSE;
177 }
178 }
179 else
180 {
181 if (TargetName[0] != 0)
182 {
184 return FALSE;
185 }
186 else
187 {
189 }
190 }
191 }
192
193 if (TargetName[0] == 0)
194 {
196 return FALSE;
197 }
198
199 if (SourceName[0] == 0)
200 {
202 return FALSE;
203 }
204
205 return TRUE;
206}
207
208static BOOL WINAPI StopLoop(DWORD dwCtrlType)
209{
211 PingCount = 0;
212
213 return TRUE;
214}
215
217{
218 WORD wVersionRequested;
219 WSADATA WsaData;
220 INT Status;
221 PHOSTENT phe;
222 CHAR aTargetName[256];
224
225 wVersionRequested = MAKEWORD(2, 2);
226
227 Status = WSAStartup(wVersionRequested, &WsaData);
228 if (Status != 0)
229 {
231 return FALSE;
232 }
233
234 if (!WideCharToMultiByte(CP_ACP, 0, TargetName, -1, aTargetName,
235 sizeof(aTargetName), NULL, NULL))
236 {
238 return FALSE;
239 }
240
241 phe = NULL;
242 TargetAddr = inet_addr(aTargetName);
243 if (TargetAddr == INADDR_NONE)
244 {
245 phe = gethostbyname(aTargetName);
246 if (phe == NULL)
247 {
249 return FALSE;
250 }
251
252 CopyMemory(&TargetAddr, phe->h_addr, phe->h_length);
253 }
254
255 Target.S_un.S_addr = TargetAddr;
256 swprintf(TargetIP, L"%d.%d.%d.%d", Target.S_un.S_un_b.s_b1,
257 Target.S_un.S_un_b.s_b2,
258 Target.S_un.S_un_b.s_b3,
259 Target.S_un.S_un_b.s_b4);
260
261 if (!WideCharToMultiByte(CP_ACP, 0, SourceName, -1, aTargetName,
262 sizeof(aTargetName), NULL, NULL))
263 {
265 return FALSE;
266 }
267
268 SourceAddr = inet_addr(aTargetName);
269 if (SourceAddr == INADDR_NONE)
270 {
272 return FALSE;
273 }
274
276
277 return TRUE;
278}
279
281{
282 WSACleanup();
283}
284
286{
288 {
290 {
291 /* This should not happen, but we fall
292 back to GetCurrentTick() if it does */
293 Time->u.LowPart = (ULONG)GetTickCount();
294 Time->u.HighPart = 0;
295
296 /* 1 tick per millisecond for GetCurrentTick() */
298 /* GetCurrentTick() cannot handle microseconds */
300
302 }
303 }
304 else
305 {
306 Time->u.LowPart = (ULONG)GetTickCount();
307 Time->u.HighPart = 0;
308 }
309}
310
312{
313 WCHAR Convstr[40];
314 LARGE_INTEGER LargeTime;
315 LPWSTR ms;
316
318
319 _i64tow(LargeTime.QuadPart, Convstr, 10);
320 wcscpy(String, Convstr);
321 ms = String + wcslen(String);
323}
324
326{
327 LARGE_INTEGER RelativeTime;
328 LARGE_INTEGER LargeTime;
329 LARGE_INTEGER SentTime;
330 DWORD Ret;
331 BYTE TargetHW[6];
332 ULONG Size;
333 WCHAR Sign[2];
334 WCHAR Time[100];
335 WCHAR StrHwAddr[18];
336
337 QueryTime(&SentTime);
338 Size = sizeof(TargetHW);
339 memset(TargetHW, 0xff, Size);
340 ++Sent;
341 Ret = SendARP(TargetAddr, SourceAddr, (PULONG)TargetHW, &Size);
342 if (Ret == ERROR_SUCCESS)
343 {
344 QueryTime(&LargeTime);
345
346 RelativeTime.QuadPart = (LargeTime.QuadPart - SentTime.QuadPart);
347
348 if ((RelativeTime.QuadPart / TicksPerMs.QuadPart) < 1)
349 {
350 wcscpy(Sign, L"<");
351 LoadString(GetModuleHandle(NULL), IDS_1MS, Time, sizeof(Time) / sizeof(WCHAR));
352 }
353 else
354 {
355 wcscpy(Sign, L"=");
356 TimeToMsString(Time, sizeof(Time) / sizeof(WCHAR), RelativeTime);
357 }
358
359 swprintf(StrHwAddr, L"%02x:%02x:%02x:%02x:%02x:%02x", TargetHW[0], TargetHW[1],
360 TargetHW[2], TargetHW[3],
361 TargetHW[4], TargetHW[5]);
363 Received++;
364
365 return TRUE;
366 }
367
368 return FALSE;
369}
370
372{
373 UINT Count;
374 LARGE_INTEGER PerformanceCounterFrequency;
375
376 PingCount = 4;
377 Timeout = 1000;
379
380 UsePerformanceCounter = QueryPerformanceFrequency(&PerformanceCounterFrequency);
381
383 {
384 /* Performance counters may return incorrect results on some multiprocessor
385 platforms so we restrict execution on the first processor. This may fail
386 on Windows NT so we fall back to GetCurrentTick() for timing */
389
390 /* Convert frequency to ticks per millisecond */
391 TicksPerMs.QuadPart = PerformanceCounterFrequency.QuadPart / 1000;
392 /* And to ticks per microsecond */
393 TicksPerUs.QuadPart = PerformanceCounterFrequency.QuadPart / 1000000;
394 }
396 {
397 /* 1 tick per millisecond for GetCurrentTick() */
399 /* GetCurrentTick() cannot handle microseconds */
401 }
402
403 if (!ParseCmdline(argc, argv) || !Setup())
404 {
405 return 1;
406 }
407
409
410 Count = 0;
411 while (Count < PingCount || NeverStop)
412 {
413 Ping();
414 Count++;
415 if (Count < PingCount || NeverStop)
416 Sleep(Timeout);
417 }
418
419 Cleanup();
420
422
423 return 0;
424}
static int argc
Definition: ServiceArgs.c:12
char * va_list
Definition: acmsvcex.h:78
#define va_end(ap)
Definition: acmsvcex.h:90
#define va_start(ap, A)
Definition: acmsvcex.h:91
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn UINT32 *TableIdx UINT32 ACPI_TABLE_HEADER *OutTableHeader ACPI_TABLE_HEADER **OutTable ACPI_HANDLE UINT32 ACPI_WALK_CALLBACK ACPI_WALK_CALLBACK void void **ReturnValue UINT32 ACPI_BUFFER *RetPathPtr ACPI_OBJECT_HANDLER void *Data ACPI_OBJECT_HANDLER void **Data ACPI_STRING ACPI_OBJECT_LIST ACPI_BUFFER *ReturnObjectBuffer ACPI_DEVICE_INFO **ReturnBuffer ACPI_HANDLE ACPI_HANDLE ACPI_HANDLE *OutHandle ACPI_HANDLE *OutHandle void *Context void *Context ACPI_EVENT_HANDLER Handler UINT32 UINT32 ACPI_GPE_HANDLER void *Context UINT32 ACPI_NOTIFY_HANDLER void *Context ACPI_ADR_SPACE_TYPE ACPI_ADR_SPACE_HANDLER ACPI_ADR_SPACE_SETUP Setup
Definition: acpixf.h:834
UINT Received
Definition: arping.c:40
WCHAR SourceName[256]
Definition: arping.c:28
ULONG Timeout
Definition: arping.c:35
DWORD TargetAddr
Definition: arping.c:30
static BOOL WINAPI StopLoop(DWORD dwCtrlType)
Definition: arping.c:208
static VOID QueryTime(PLARGE_INTEGER Time)
Definition: arping.c:285
BOOL UsePerformanceCounter
Definition: arping.c:38
static BOOL ParseCmdline(int argc, LPWSTR argv[])
Definition: arping.c:117
WCHAR TargetName[256]
Definition: arping.c:27
HANDLE hStdOutput
Definition: arping.c:34
BOOL NeverStop
Definition: arping.c:25
WCHAR TargetIP[16]
Definition: arping.c:31
LARGE_INTEGER TicksPerUs
Definition: arping.c:37
static VOID TimeToMsString(LPWSTR String, ULONG Length, LARGE_INTEGER Time)
Definition: arping.c:311
LARGE_INTEGER TicksPerMs
Definition: arping.c:36
SOCKADDR_IN Target
Definition: arping.c:33
void FormatOutput(UINT uID,...)
Definition: arping.c:42
UINT PingCount
Definition: arping.c:26
WCHAR SourceIP[16]
Definition: arping.c:32
UINT Sent
Definition: arping.c:39
DWORD SourceAddr
Definition: arping.c:29
#define IDS_USAGE
Definition: resource.h:3
#define INADDR_NONE
Definition: tcp.c:42
#define IDS_BAD_PARAMETER
Definition: resource.h:10
#define IDS_UNKNOWN_HOST
Definition: resource.h:13
#define IDS_REPLY_FROM
Definition: resource.h:18
#define IDS_BAD_OPTION
Definition: resource.h:9
HANDLE WINAPI GetStdHandle(IN DWORD nStdHandle)
Definition: console.c:203
_In_ ULONG _In_opt_ WDFREQUEST _In_opt_ PVOID _In_ size_t _In_ PVOID _In_ size_t _Out_ size_t * DataLength
Definition: cdrom.h:1444
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
@ Sign
Definition: msg.c:1064
#define GetProcessHeap()
Definition: compat.h:736
#define CP_ACP
Definition: compat.h:109
#define HeapAlloc
Definition: compat.h:733
#define HeapFree(x, y, z)
Definition: compat.h:735
#define WideCharToMultiByte
Definition: compat.h:111
BOOL WINAPI DECLSPEC_HOTPATCH SetConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine, BOOL Add)
Definition: console.c:2109
DWORD WINAPI GetFileType(HANDLE hFile)
Definition: fileinfo.c:269
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
BOOL WINAPI QueryPerformanceFrequency(OUT PLARGE_INTEGER lpFrequency)
Definition: perfcnt.c:45
BOOL WINAPI QueryPerformanceCounter(OUT PLARGE_INTEGER lpPerformanceCount)
Definition: perfcnt.c:23
DWORD_PTR WINAPI SetThreadAffinityMask(IN HANDLE hThread, IN DWORD_PTR dwThreadAffinityMask)
Definition: thread.c:662
DWORD WINAPI GetTickCount(VOID)
Definition: time.c:455
#define swprintf
Definition: precomp.h:40
static const WCHAR Cleanup[]
Definition: register.c:80
INT WINAPI WSAStartup(IN WORD wVersionRequested, OUT LPWSADATA lpWSAData)
Definition: startup.c:113
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
Status
Definition: gdiplustypes.h:25
PHOSTENT WSAAPI gethostbyname(IN const char FAR *name)
Definition: getxbyxx.c:221
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
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1594
_Must_inspect_result_ _In_ USAGE _In_ USHORT _In_ USAGE Usage
Definition: hidpi.h:384
#define UINT_MAX
Definition: limits.h:41
_Check_return_ unsigned long __cdecl wcstoul(_In_z_ const wchar_t *_Str, _Out_opt_ _Deref_post_z_ wchar_t **_EndPtr, _In_ int _Radix)
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
DWORD WINAPI SendARP(IPAddr DestIP, IPAddr SrcIP, PULONG pMacAddr, PULONG PhyAddrLen)
#define inet_addr(cp)
Definition: inet.h:98
wchar_t *CDECL _i64tow(__int64 value, wchar_t *string, int radix)
Definition: itow.c:17
#define PCHAR
Definition: match.c:90
#define IDS_ARPING_STATISTICS
Definition: resource.h:16
#define IDS_SRC_MUST_BE_SPECIFIED
Definition: resource.h:10
#define IDS_BAD_VALUE_OPTION_N
Definition: resource.h:11
#define IDS_MS
Definition: resource.h:13
#define IDS_1MS
Definition: resource.h:14
#define IDS_DEST_MUST_BE_SPECIFIED
Definition: resource.h:7
#define IDS_BAD_OPTION_FORMAT
Definition: resource.h:4
#define IDS_ARPING_TO_FROM
Definition: resource.h:12
#define IDS_COULD_NOT_INIT_WINSOCK
Definition: resource.h:8
static __ms_va_list valist
Definition: printf.c:66
static PLARGE_INTEGER Time
Definition: time.c:105
#define argv
Definition: mplay32.c:18
unsigned int UINT
Definition: ndis.h:50
int Count
Definition: noreturn.cpp:7
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define L(x)
Definition: ntvdm.h:50
static void Ping(void)
Definition: ping.c:419
int wmain()
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
#define memset(x, y, z)
Definition: compat.h:39
short h_length
Definition: winsock.h:137
Definition: tcpip.h:126
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
uint32_t * PULONG
Definition: typedefs.h:59
#define MAKEWORD(a, b)
Definition: typedefs.h:248
int32_t INT
Definition: typedefs.h:58
uint32_t ULONG
Definition: typedefs.h:59
char * PCHAR
Definition: typedefs.h:51
LONGLONG QuadPart
Definition: typedefs.h:114
struct _LARGE_INTEGER::@2290 u
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFSTRING String
Definition: wdfdevice.h:2433
_In_ WDFIOTARGET Target
Definition: wdfrequest.h:306
#define FormatMessage
Definition: winbase.h:3730
#define STD_OUTPUT_HANDLE
Definition: winbase.h:268
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define FORMAT_MESSAGE_FROM_STRING
Definition: winbase.h:421
HANDLE WINAPI GetCurrentThread(void)
Definition: proc.c:1148
#define CopyMemory
Definition: winbase.h:1710
#define GetModuleHandle
Definition: winbase.h:3762
#define FORMAT_MESSAGE_ALLOCATE_BUFFER
Definition: winbase.h:419
#define FILE_TYPE_CHAR
Definition: winbase.h:260
#define WriteConsole
Definition: wincon.h:784
#define WINAPI
Definition: msvc.h:6
#define CP_OEMCP
Definition: winnls.h:231
int PASCAL FAR WSACleanup(void)
Definition: startup.c:60
#define LoadString
Definition: winuser.h:5819
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
char CHAR
Definition: xmlstorage.h:175
unsigned char BYTE
Definition: xxhash.c:193