Author: pschweitzer
Date: Sun Nov 29 19:44:29 2015
New Revision: 70212
URL:
http://svn.reactos.org/svn/reactos?rev=70212&view=rev
Log:
[ARPING]
Implement an arping tool. Some portions of code are just plain copy/paste from ping tool
code (booh, it's bad!).
It was designed and tested on W2K3.
It's in RosApps for two major reasons: such a tool doesn't exist by default in
Windows 2K3.
And it doesn't work in ReactOS.
Added:
trunk/rosapps/applications/cmdutils/arping/
trunk/rosapps/applications/cmdutils/arping/CMakeLists.txt (with props)
trunk/rosapps/applications/cmdutils/arping/arping.c (with props)
trunk/rosapps/applications/cmdutils/arping/arping.rc (with props)
trunk/rosapps/applications/cmdutils/arping/lang/
trunk/rosapps/applications/cmdutils/arping/lang/en-US.rc (with props)
trunk/rosapps/applications/cmdutils/arping/resource.h (with props)
Modified:
trunk/rosapps/applications/cmdutils/CMakeLists.txt
Modified: trunk/rosapps/applications/cmdutils/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/trunk/rosapps/applications/cmdutils/CMak…
==============================================================================
--- trunk/rosapps/applications/cmdutils/CMakeLists.txt [iso-8859-1] (original)
+++ trunk/rosapps/applications/cmdutils/CMakeLists.txt [iso-8859-1] Sun Nov 29 19:44:29
2015
@@ -1,4 +1,5 @@
add_subdirectory(appwiz)
+add_subdirectory(arping)
add_subdirectory(cat)
add_subdirectory(hackssign)
add_subdirectory(ntfsinfo)
Added: trunk/rosapps/applications/cmdutils/arping/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/trunk/rosapps/applications/cmdutils/arpi…
==============================================================================
--- trunk/rosapps/applications/cmdutils/arping/CMakeLists.txt (added)
+++ trunk/rosapps/applications/cmdutils/arping/CMakeLists.txt [iso-8859-1] Sun Nov 29
19:44:29 2015
@@ -0,0 +1,11 @@
+
+add_definitions(-D__USE_W32_SOCKETS)
+add_executable(arping arping.c arping.rc)
+set_module_type(arping win32cui UNICODE)
+add_importlibs(arping user32 ws2_32 iphlpapi msvcrt kernel32)
+
+if(MSVC)
+ add_importlibs(arping ntdll)
+endif()
+
+add_cd_file(TARGET arping DESTINATION reactos/system32 FOR all)
Propchange: trunk/rosapps/applications/cmdutils/arping/CMakeLists.txt
------------------------------------------------------------------------------
svn:eol-style = native
Added: trunk/rosapps/applications/cmdutils/arping/arping.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rosapps/applications/cmdutils/arpi…
==============================================================================
--- trunk/rosapps/applications/cmdutils/arping/arping.c (added)
+++ trunk/rosapps/applications/cmdutils/arping/arping.c [iso-8859-1] Sun Nov 29 19:44:29
2015
@@ -0,0 +1,424 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS ping utility
+ * FILE: applications/cmdutils/arping/arping.c
+ * PURPOSE: Network test utility
+ * PROGRAMMERS: Pierre Schweitzer <pierre(a)reactos.org>
+ */
+
+#define WIN32_NO_STATUS
+#include <stdarg.h>
+#include <windef.h>
+#include <winbase.h>
+#include <winuser.h>
+#include <winnls.h>
+#include <wincon.h>
+#define _INC_WINDOWS
+#include <ws2tcpip.h>
+#include <iphlpapi.h>
+#include <ws2def.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "resource.h"
+
+BOOL NeverStop;
+UINT PingCount;
+WCHAR TargetName[256];
+WCHAR SourceName[256];
+DWORD SourceAddr;
+DWORD TargetAddr;
+WCHAR TargetIP[16];
+WCHAR SourceIP[16];
+SOCKADDR_IN Target;
+HANDLE hStdOutput;
+ULONG Timeout;
+LARGE_INTEGER TicksPerMs;
+LARGE_INTEGER TicksPerUs;
+BOOL UsePerformanceCounter;
+UINT Sent;
+UINT Received;
+
+void FormatOutput(UINT uID, ...)
+{
+ va_list valist;
+
+ WCHAR Buf[1024];
+ CHAR AnsiBuf[1024];
+ LPWSTR pBuf = Buf;
+ PCHAR pAnsiBuf = AnsiBuf;
+ WCHAR Format[1024];
+ DWORD written;
+ UINT DataLength;
+ int AnsiLength;
+
+ if (!LoadString(GetModuleHandle(NULL), uID,
+ Format, sizeof(Format) / sizeof(WCHAR)))
+ {
+ return;
+ }
+
+ va_start(valist, uID);
+
+ DataLength = FormatMessage(FORMAT_MESSAGE_FROM_STRING, Format, 0, 0, Buf,\
+ sizeof(Buf) / sizeof(WCHAR), &valist);
+
+ if(!DataLength)
+ {
+ if(GetLastError() != ERROR_INSUFFICIENT_BUFFER)
+ {
+ va_end(valist);
+ return;
+ }
+
+ DataLength = FormatMessage(FORMAT_MESSAGE_FROM_STRING |\
+ FORMAT_MESSAGE_ALLOCATE_BUFFER,\
+ Format, 0, 0, (LPWSTR)&pBuf, 0, &valist);
+ }
+
+ if(!DataLength)
+ {
+ va_end(valist);
+ return;
+ }
+
+ if(GetFileType(hStdOutput) == FILE_TYPE_CHAR)
+ {
+ /* Is a console or a printer */
+ WriteConsole(hStdOutput, pBuf, DataLength, &written, NULL);
+ }
+ else
+ {
+ /* Is a pipe, socket, file or other */
+ AnsiLength = WideCharToMultiByte(CP_ACP, 0, pBuf, DataLength,\
+ NULL, 0, NULL, NULL);
+
+ if(AnsiLength >= sizeof(AnsiBuf))
+ pAnsiBuf = (PCHAR)HeapAlloc(GetProcessHeap(), 0, AnsiLength);
+
+ AnsiLength = WideCharToMultiByte(CP_OEMCP, 0, pBuf, DataLength,\
+ pAnsiBuf, AnsiLength, " ", NULL);
+
+ WriteFile(hStdOutput, pAnsiBuf, AnsiLength, &written, NULL);
+
+ if(pAnsiBuf != AnsiBuf)
+ HeapFree(NULL, 0, pAnsiBuf);
+ }
+
+ if(pBuf != Buf)
+ LocalFree(pBuf);
+}
+
+static VOID Usage(VOID)
+{
+ FormatOutput(IDS_USAGE);
+}
+
+static BOOL ParseCmdline(int argc, LPWSTR argv[])
+{
+ INT i;
+
+ if (argc < 3)
+ {
+ Usage();
+ return FALSE;
+ }
+
+ for (i = 1; i < argc; i++)
+ {
+ if (argv[i][0] == L'-' || argv[i][0] == L'/')
+ {
+ switch (argv[i][1])
+ {
+ case L't': NeverStop = TRUE; break;
+ case L'n':
+ if (i + 1 < argc)
+ {
+ PingCount = wcstoul(argv[++i], NULL, 0);
+
+ if (PingCount == 0)
+ {
+ FormatOutput(IDS_BAD_VALUE_OPTION_N, UINT_MAX);
+ return FALSE;
+ }
+ }
+ else
+ {
+ FormatOutput(IDS_BAD_OPTION_FORMAT, argv[i]);
+ return FALSE;
+ }
+ break;
+
+ case L's':
+ if (SourceName[0] != 0)
+ {
+ FormatOutput(IDS_BAD_PARAMETER, argv[i]);
+ return FALSE;
+ }
+
+ if (i + 1 < argc)
+ {
+ wcscpy(SourceName, argv[++i]);
+ }
+ else
+ {
+ FormatOutput(IDS_BAD_OPTION_FORMAT, argv[i]);
+ return FALSE;
+ }
+ break;
+
+ case '?':
+ Usage();
+ return FALSE;
+
+ default:
+ FormatOutput(IDS_BAD_OPTION, argv[i]);
+ return FALSE;
+ }
+ }
+ else
+ {
+ if (TargetName[0] != 0)
+ {
+ FormatOutput(IDS_BAD_PARAMETER, argv[i]);
+ return FALSE;
+ }
+ else
+ {
+ wcscpy(TargetName, argv[i]);
+ }
+ }
+ }
+
+ if (TargetName[0] == 0)
+ {
+ FormatOutput(IDS_DEST_MUST_BE_SPECIFIED);
+ return FALSE;
+ }
+
+ if (SourceName[0] == 0)
+ {
+ FormatOutput(IDS_SRC_MUST_BE_SPECIFIED);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static BOOL WINAPI StopLoop(DWORD dwCtrlType)
+{
+ NeverStop = FALSE;
+ PingCount = 0;
+
+ return TRUE;
+}
+
+static BOOL Setup(VOID)
+{
+ WORD wVersionRequested;
+ WSADATA WsaData;
+ INT Status;
+ PHOSTENT phe;
+ CHAR aTargetName[256];
+ IN_ADDR Target;
+
+ wVersionRequested = MAKEWORD(2, 2);
+
+ Status = WSAStartup(wVersionRequested, &WsaData);
+ if (Status != 0)
+ {
+ FormatOutput(IDS_COULD_NOT_INIT_WINSOCK);
+ return FALSE;
+ }
+
+ if (!WideCharToMultiByte(CP_ACP, 0, TargetName, -1, aTargetName,
+ sizeof(aTargetName), NULL, NULL))
+ {
+ FormatOutput(IDS_UNKNOWN_HOST, TargetName);
+ return FALSE;
+ }
+
+ phe = NULL;
+ TargetAddr = inet_addr(aTargetName);
+ if (TargetAddr == INADDR_NONE)
+ {
+ phe = gethostbyname(aTargetName);
+ if (phe == NULL)
+ {
+ FormatOutput(IDS_UNKNOWN_HOST, TargetName);
+ return FALSE;
+ }
+
+ CopyMemory(&TargetAddr, phe->h_addr, phe->h_length);
+ }
+
+ Target.S_un.S_addr = TargetAddr;
+ swprintf(TargetIP, L"%d.%d.%d.%d", Target.S_un.S_un_b.s_b1,
+ Target.S_un.S_un_b.s_b2,
+ Target.S_un.S_un_b.s_b3,
+ Target.S_un.S_un_b.s_b4);
+
+ if (!WideCharToMultiByte(CP_ACP, 0, SourceName, -1, aTargetName,
+ sizeof(aTargetName), NULL, NULL))
+ {
+ FormatOutput(IDS_UNKNOWN_HOST, SourceName);
+ return FALSE;
+ }
+
+ SourceAddr = inet_addr(aTargetName);
+ if (SourceAddr == INADDR_NONE)
+ {
+ FormatOutput(IDS_UNKNOWN_HOST, SourceName);
+ return FALSE;
+ }
+
+ SetConsoleCtrlHandler(StopLoop, TRUE);
+
+ return TRUE;
+}
+
+static VOID Cleanup(VOID)
+{
+ WSACleanup();
+}
+
+static VOID QueryTime(PLARGE_INTEGER Time)
+{
+ if (UsePerformanceCounter)
+ {
+ if (QueryPerformanceCounter(Time) == 0)
+ {
+ /* This should not happen, but we fall
+ back to GetCurrentTick() if it does */
+ Time->u.LowPart = (ULONG)GetTickCount();
+ Time->u.HighPart = 0;
+
+ /* 1 tick per millisecond for GetCurrentTick() */
+ TicksPerMs.QuadPart = 1;
+ /* GetCurrentTick() cannot handle microseconds */
+ TicksPerUs.QuadPart = 1;
+
+ UsePerformanceCounter = FALSE;
+ }
+ }
+ else
+ {
+ Time->u.LowPart = (ULONG)GetTickCount();
+ Time->u.HighPart = 0;
+ }
+}
+
+static VOID TimeToMsString(LPWSTR String, ULONG Length, LARGE_INTEGER Time)
+{
+ WCHAR Convstr[40];
+ LARGE_INTEGER LargeTime;
+ LPWSTR ms;
+
+ LargeTime.QuadPart = Time.QuadPart / TicksPerMs.QuadPart;
+
+ _i64tow(LargeTime.QuadPart, Convstr, 10);
+ wcscpy(String, Convstr);
+ ms = String + wcslen(String);
+ LoadString(GetModuleHandle(NULL), IDS_MS, ms, Length - (ms - String));
+}
+
+static BOOL Ping(VOID)
+{
+ LARGE_INTEGER RelativeTime;
+ LARGE_INTEGER LargeTime;
+ LARGE_INTEGER SentTime;
+ DWORD Ret;
+ BYTE TargetHW[6];
+ ULONG Size;
+ WCHAR Sign[2];
+ WCHAR Time[100];
+ WCHAR StrHwAddr[18];
+
+ QueryTime(&SentTime);
+ Size = sizeof(TargetHW);
+ memset(TargetHW, 0xff, Size);
+ ++Sent;
+ Ret = SendARP(TargetAddr, SourceAddr, (PULONG)TargetHW, &Size);
+ if (Ret == ERROR_SUCCESS)
+ {
+ QueryTime(&LargeTime);
+
+ RelativeTime.QuadPart = (LargeTime.QuadPart - SentTime.QuadPart);
+
+ if ((RelativeTime.QuadPart / TicksPerMs.QuadPart) < 1)
+ {
+ wcscpy(Sign, L"<");
+ LoadString(GetModuleHandle(NULL), IDS_1MS, Time, sizeof(Time) /
sizeof(WCHAR));
+ }
+ else
+ {
+ wcscpy(Sign, L"=");
+ TimeToMsString(Time, sizeof(Time) / sizeof(WCHAR), RelativeTime);
+ }
+
+ swprintf(StrHwAddr, L"%02x:%02x:%02x:%02x:%02x:%02x", TargetHW[0],
TargetHW[1],
+ TargetHW[2], TargetHW[3],
+ TargetHW[4], TargetHW[5]);
+ FormatOutput(IDS_REPLY_FROM, TargetIP, StrHwAddr, Sign, Time);
+ Received++;
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+int wmain(int argc, LPWSTR argv[])
+{
+ UINT Count;
+ LARGE_INTEGER PerformanceCounterFrequency;
+
+ PingCount = 4;
+ Timeout = 1000;
+ hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
+
+ UsePerformanceCounter = QueryPerformanceFrequency(&PerformanceCounterFrequency);
+
+ if (UsePerformanceCounter)
+ {
+ /* Performance counters may return incorrect results on some multiprocessor
+ platforms so we restrict execution on the first processor. This may fail
+ on Windows NT so we fall back to GetCurrentTick() for timing */
+ if (SetThreadAffinityMask (GetCurrentThread(), 1) == 0)
+ UsePerformanceCounter = FALSE;
+
+ /* Convert frequency to ticks per millisecond */
+ TicksPerMs.QuadPart = PerformanceCounterFrequency.QuadPart / 1000;
+ /* And to ticks per microsecond */
+ TicksPerUs.QuadPart = PerformanceCounterFrequency.QuadPart / 1000000;
+ }
+ if (!UsePerformanceCounter)
+ {
+ /* 1 tick per millisecond for GetCurrentTick() */
+ TicksPerMs.QuadPart = 1;
+ /* GetCurrentTick() cannot handle microseconds */
+ TicksPerUs.QuadPart = 1;
+ }
+
+ if (!ParseCmdline(argc, argv) || !Setup())
+ {
+ return 1;
+ }
+
+ FormatOutput(IDS_ARPING_TO_FROM, TargetIP, SourceName);
+
+ Count = 0;
+ while (Count < PingCount || NeverStop)
+ {
+ Ping();
+ Count++;
+ if (Count < PingCount || NeverStop)
+ Sleep(Timeout);
+ }
+
+ Cleanup();
+
+ FormatOutput(IDS_ARPING_STATISTICS, Sent, Received);
+
+ return 0;
+}
Propchange: trunk/rosapps/applications/cmdutils/arping/arping.c
------------------------------------------------------------------------------
svn:eol-style = native
Added: trunk/rosapps/applications/cmdutils/arping/arping.rc
URL:
http://svn.reactos.org/svn/reactos/trunk/rosapps/applications/cmdutils/arpi…
==============================================================================
--- trunk/rosapps/applications/cmdutils/arping/arping.rc (added)
+++ trunk/rosapps/applications/cmdutils/arping/arping.rc [iso-8859-1] Sun Nov 29 19:44:29
2015
@@ -0,0 +1,15 @@
+#include <windef.h>
+
+#include "resource.h"
+
+#define REACTOS_STR_FILE_DESCRIPTION "ReactOS TCP/IPv4 Win32 ARP Ping"
+#define REACTOS_STR_INTERNAL_NAME "arpping"
+#define REACTOS_STR_ORIGINAL_FILENAME "arpping.exe"
+#include <reactos/version.rc>
+
+/* UTF-8 */
+#pragma code_page(65001)
+
+#ifdef LANGUAGE_EN_US
+ #include "lang/en-US.rc"
+#endif
Propchange: trunk/rosapps/applications/cmdutils/arping/arping.rc
------------------------------------------------------------------------------
svn:eol-style = native
Added: trunk/rosapps/applications/cmdutils/arping/lang/en-US.rc
URL:
http://svn.reactos.org/svn/reactos/trunk/rosapps/applications/cmdutils/arpi…
==============================================================================
--- trunk/rosapps/applications/cmdutils/arping/lang/en-US.rc (added)
+++ trunk/rosapps/applications/cmdutils/arping/lang/en-US.rc [iso-8859-1] Sun Nov 29
19:44:29 2015
@@ -0,0 +1,25 @@
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+STRINGTABLE
+BEGIN
+ IDS_USAGE "\nUsage: arping [-t] [-n count] -s source-ip destination-host\n\n\
+Options:\n\
+ -t Ping the specified host until stopped.\n\
+ To stop - type Control-C.\n\
+ -n count Number of probes to send.\n\
+ -s Use this source IP.\n\n\0"
+ IDS_BAD_OPTION_FORMAT "Bad option format %1.\n\0"
+ IDS_BAD_OPTION "Bad option %1.\n\0"
+ IDS_BAD_PARAMETER "Bad parameter %1.\n\0"
+ IDS_DEST_MUST_BE_SPECIFIED "Name or IP address of destination host must be
specified.\n\0"
+ IDS_COULD_NOT_INIT_WINSOCK "Could not initialize winsock dll.\n\0"
+ IDS_UNKNOWN_HOST "Unknown host %1.\n\0"
+ IDS_SRC_MUST_BE_SPECIFIED "IP address of source host must be
specified.\n\0"
+ IDS_BAD_VALUE_OPTION_N "Bad value for option -n, valid range is from 1 to
%1!u!.\n\0"
+ IDS_ARPING_TO_FROM "ARPING %1 from %2\n\0"
+ IDS_MS "ms\0"
+ IDS_1MS "1ms\0"
+ IDS_REPLY_FROM "Unicast reply from %1 [%2] %3%4\n\0"
+ IDS_ARPING_STATISTICS "Sent %1!u! probes\n\
+Received %2!u! response(s)\n\0"
+END
Propchange: trunk/rosapps/applications/cmdutils/arping/lang/en-US.rc
------------------------------------------------------------------------------
svn:eol-style = native
Added: trunk/rosapps/applications/cmdutils/arping/resource.h
URL:
http://svn.reactos.org/svn/reactos/trunk/rosapps/applications/cmdutils/arpi…
==============================================================================
--- trunk/rosapps/applications/cmdutils/arping/resource.h (added)
+++ trunk/rosapps/applications/cmdutils/arping/resource.h [iso-8859-1] Sun Nov 29 19:44:29
2015
@@ -0,0 +1,16 @@
+#pragma once
+
+#define IDS_USAGE 0
+#define IDS_BAD_OPTION_FORMAT 1
+#define IDS_BAD_OPTION 2
+#define IDS_BAD_PARAMETER 3
+#define IDS_DEST_MUST_BE_SPECIFIED 4
+#define IDS_COULD_NOT_INIT_WINSOCK 5
+#define IDS_UNKNOWN_HOST 6
+#define IDS_SRC_MUST_BE_SPECIFIED 7
+#define IDS_BAD_VALUE_OPTION_N 8
+#define IDS_ARPING_TO_FROM 9
+#define IDS_MS 10
+#define IDS_1MS 11
+#define IDS_REPLY_FROM 12
+#define IDS_ARPING_STATISTICS 13
Propchange: trunk/rosapps/applications/cmdutils/arping/resource.h
------------------------------------------------------------------------------
svn:eol-style = native