4 * Copyright (C) 2010 Trey Hunner
5 * Copyright (C) 2018 Isira Seneviratne
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
34 #include "wine/debug.h"
35 #include "wine/heap.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(ping
);
39 static void usage(void)
41 printf("Usage: ping [-n count] [-w timeout] [-l buffer_length] target_name\n\n"
43 " -n Number of echo requests to send.\n"
44 " -w Timeout in milliseconds to wait for each reply.\n"
45 " -l Length of send buffer.\n");
48 int __cdecl
main(int argc
, char** argv
)
50 unsigned int n
= 4, i
, w
= 4000, l
= 32;
52 int rec
= 0, lost
= 0, min
= INT_MAX
, max
= 0;
56 DWORD retval
, reply_size
;
57 char *send_data
, ip
[100], *hostname
= NULL
, rtt
[16];
60 ICMP_ECHO_REPLY
*reply
;
62 struct hostent
*remote_host
;
70 for (i
= 1; i
< argc
; i
++)
72 if (argv
[i
][0] == '-' || argv
[i
][0] == '/')
79 printf( "Missing value for option %s\n", argv
[i
] );
85 printf("Bad value for option -n, valid range is from 1 to 4294967295.\n");
92 printf( "Missing value for option %s\n", argv
[i
] );
98 printf("Bad value for option -w.\n");
105 printf( "Missing value for option %s\n", argv
[i
] );
111 printf("Bad value for option -l.\n");
120 WINE_FIXME( "this command currently only supports the -n, -w and -l parameters.\n" );
128 printf( "Bad argument %s\n", argv
[i
] );
137 printf("Pass a host name.\n");
141 res
= WSAStartup(MAKEWORD(2, 2), &wsa
);
144 printf("WSAStartup failed: %d\n", res
);
148 remote_host
= gethostbyname(hostname
);
149 if (remote_host
== NULL
)
151 printf("Ping request could not find host %s. Please check the name and try again.\n",
156 addr
.s_addr
= *(u_long
*) remote_host
->h_addr_list
[0];
157 strcpy(ip
, inet_ntoa(addr
));
158 ipaddr
= inet_addr(ip
);
159 if (ipaddr
== INADDR_NONE
)
161 printf("Could not get IP address of host %s.", hostname
);
165 icmp_file
= IcmpCreateFile();
167 send_data
= heap_alloc_zero(l
);
168 reply_size
= sizeof(ICMP_ECHO_REPLY
) + l
+ 8;
169 /* The buffer has to hold 8 more bytes of data (the size of an ICMP error message). */
170 reply_buffer
= heap_alloc(reply_size
);
171 if (reply_buffer
== NULL
)
173 printf("Unable to allocate memory to reply buffer.\n");
177 printf("Pinging %s [%s] with %d bytes of data:\n", hostname
, ip
, l
);
178 for (i
= 0; i
< n
; i
++)
181 retval
= IcmpSendEcho(icmp_file
, ipaddr
, send_data
, l
,
182 NULL
, reply_buffer
, reply_size
, w
);
185 reply
= (ICMP_ECHO_REPLY
*) reply_buffer
;
186 if (reply
->RoundTripTime
>= 1)
187 sprintf(rtt
, "=%d", reply
->RoundTripTime
);
190 printf("Reply from %s: bytes=%d time%sms TTL=%d\n", ip
, l
,
191 rtt
, reply
->Options
.Ttl
);
192 if (reply
->RoundTripTime
> max
)
193 max
= reply
->RoundTripTime
;
194 if (reply
->RoundTripTime
< min
)
195 min
= reply
->RoundTripTime
;
196 avg
+= reply
->RoundTripTime
;
201 if (GetLastError() == IP_REQ_TIMED_OUT
)
202 puts("Request timed out.");
204 puts("PING: transmit failed. General failure.");
207 if (i
< n
- 1) Sleep(1000);
210 printf("\nPing statistics for %s\n", ip
);
211 printf("\tPackets: Sent = %d, Received = %d, Lost = %d (%.0f%% loss)\n",
212 n
, rec
, lost
, (float) lost
/ n
* 100);
216 printf("Approximate round trip times in milli-seconds:\n");
217 printf("\tMinimum = %dms, Maximum = %dms, Average = %.0fms\n",
221 heap_free(reply_buffer
);