ping: Implement -l, -w, -n using IcmpSendEcho.
Signed-off-by: Isira Seneviratne <isirasen96@gmail.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
e9b3ccaca3
commit
b1e9177c13
|
@ -1,5 +1,6 @@
|
|||
MODULE = ping.exe
|
||||
APPMODE = -mconsole
|
||||
IMPORTS = ws2_32 iphlpapi
|
||||
|
||||
C_SRCS = \
|
||||
ping_main.c
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
/*
|
||||
* ping stub
|
||||
* ping program
|
||||
*
|
||||
* Copyright (C) 2010 Trey Hunner
|
||||
* Copyright (C) 2018 Isira Seneviratne
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -19,9 +21,15 @@
|
|||
|
||||
#include "config.h"
|
||||
#include "wine/port.h"
|
||||
#include "winsock2.h"
|
||||
#include "ws2tcpip.h"
|
||||
#include "iphlpapi.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <icmpapi.h>
|
||||
#include <limits.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
@ -29,25 +37,42 @@
|
|||
#include <windows.h>
|
||||
|
||||
#include "wine/debug.h"
|
||||
#include "wine/heap.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(ping);
|
||||
|
||||
static void usage(void)
|
||||
{
|
||||
printf("Usage: ping [-n count] [-w timeout] target_name\n\n"
|
||||
printf("Usage: ping [-n count] [-w timeout] [-l buffer_length] target_name\n\n"
|
||||
"Options:\n"
|
||||
" -n Number of echo requests to send.\n"
|
||||
" -w Timeout in milliseconds to wait for each reply.\n");
|
||||
" -w Timeout in milliseconds to wait for each reply.\n"
|
||||
" -l Length of send buffer.\n");
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
unsigned int n = 0;
|
||||
int optc;
|
||||
unsigned int n = 4, i = 0, w = 4000, l = 32;
|
||||
int optc, res;
|
||||
int rec = 0, lost = 0, min = INT_MAX, max = 0;
|
||||
WSADATA wsa;
|
||||
HANDLE icmp_file;
|
||||
unsigned long ipaddr;
|
||||
DWORD retval, reply_size;
|
||||
char *send_data, ip[100], *hostname, rtt[16];
|
||||
void *reply_buffer;
|
||||
struct in_addr addr;
|
||||
ICMP_ECHO_REPLY *reply;
|
||||
float avg = 0;
|
||||
struct hostent *remote_host;
|
||||
|
||||
WINE_FIXME( "this command currently just sleeps based on -n parameter\n" );
|
||||
if (argc == 1)
|
||||
{
|
||||
usage();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
while ((optc = getopt( argc, argv, "n:w:tal:fi:v:r:s:j:k:" )) != -1)
|
||||
while ((optc = getopt( argc, argv, "n:w:l:tal:fi:v:r:s:j:k:" )) != -1)
|
||||
{
|
||||
switch(optc)
|
||||
{
|
||||
|
@ -59,18 +84,119 @@ int main(int argc, char** argv)
|
|||
exit(1);
|
||||
}
|
||||
break;
|
||||
case 'w':
|
||||
w = atoi(optarg);
|
||||
if (w == 0)
|
||||
{
|
||||
printf("Bad value for option -w.\n");
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case 'l':
|
||||
l = atoi(optarg);
|
||||
if (l == 0)
|
||||
{
|
||||
printf("Bad value for option -l.\n");
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case '?':
|
||||
usage();
|
||||
exit(1);
|
||||
default:
|
||||
usage();
|
||||
WINE_FIXME( "this command currently only supports the -n parameter\n" );
|
||||
WINE_FIXME( "this command currently only supports the -n, -w and -l parameters.\n" );
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (n != 0)
|
||||
Sleep((n - 1) * 1000);
|
||||
if (argv[optind] != NULL)
|
||||
hostname = argv[optind];
|
||||
else
|
||||
{
|
||||
printf("Pass a host name.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
res = WSAStartup(MAKEWORD(2, 2), &wsa);
|
||||
if (res != 0)
|
||||
{
|
||||
printf("WSAStartup failed: %d\n", res);
|
||||
return 1;
|
||||
}
|
||||
|
||||
remote_host = gethostbyname(hostname);
|
||||
if (remote_host == NULL)
|
||||
{
|
||||
printf("Ping request could not find host %s. Please check the name and try again.\n",
|
||||
hostname);
|
||||
return 1;
|
||||
}
|
||||
|
||||
addr.s_addr = *(u_long *) remote_host->h_addr_list[0];
|
||||
strcpy(ip, inet_ntoa(addr));
|
||||
ipaddr = inet_addr(ip);
|
||||
if (ipaddr == INADDR_NONE)
|
||||
{
|
||||
printf("Could not get IP address of host %s.", hostname);
|
||||
return 1;
|
||||
}
|
||||
|
||||
icmp_file = IcmpCreateFile();
|
||||
|
||||
send_data = heap_alloc_zero(l);
|
||||
reply_size = sizeof(ICMP_ECHO_REPLY) + l + 8;
|
||||
/* The buffer has to hold 8 more bytes of data (the size of an ICMP error message). */
|
||||
reply_buffer = heap_alloc(reply_size);
|
||||
if (reply_buffer == NULL)
|
||||
{
|
||||
printf("Unable to allocate memory to reply buffer.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("Pinging %s [%s] with %d bytes of data:\n", hostname, ip, l);
|
||||
for (;;)
|
||||
{
|
||||
retval = IcmpSendEcho(icmp_file, ipaddr, send_data, l,
|
||||
NULL, reply_buffer, reply_size, w);
|
||||
if (retval != 0)
|
||||
{
|
||||
reply = (ICMP_ECHO_REPLY *) reply_buffer;
|
||||
if (reply->RoundTripTime >= 1)
|
||||
sprintf(rtt, "=%d", reply->RoundTripTime);
|
||||
else
|
||||
strcpy(rtt, "<1");
|
||||
printf("Reply from %s: bytes=%d time%sms TTL=%d\n", ip, l,
|
||||
rtt, reply->Options.Ttl);
|
||||
if (reply->RoundTripTime > max)
|
||||
max = reply->RoundTripTime;
|
||||
if (reply->RoundTripTime < min)
|
||||
min = reply->RoundTripTime;
|
||||
avg += reply->RoundTripTime;
|
||||
rec++;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Request timed out.\n");
|
||||
lost++;
|
||||
}
|
||||
i++;
|
||||
if (i == n)
|
||||
break;
|
||||
Sleep(1000);
|
||||
}
|
||||
|
||||
printf("\nPing statistics for %s\n", ip);
|
||||
printf("\tPackets: Sent = %d, Received = %d, Lost = %d (%.0f%% loss)\n",
|
||||
n, rec, lost, (float) lost / n * 100);
|
||||
if (rec != 0)
|
||||
{
|
||||
avg /= rec;
|
||||
printf("Approximate round trip times in milli-seconds:\n");
|
||||
printf("\tMinimum = %dms, Maximum = %dms, Average = %.0fms\n",
|
||||
min, max, avg);
|
||||
}
|
||||
|
||||
heap_free(reply_buffer);
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue