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"
36 WINE_DEFAULT_DEBUG_CHANNEL(ping
);
38 static void usage(void)
40 printf("Usage: ping [-n count] [-w timeout] [-l buffer_length] target_name\n\n"
42 " -n Number of echo requests to send.\n"
43 " -w Timeout in milliseconds to wait for each reply.\n"
44 " -l Length of send buffer.\n");
47 int __cdecl
main(int argc
, char** argv
)
49 unsigned int n
= 4, i
, w
= 4000, l
= 32;
51 int rec
= 0, lost
= 0, min
= INT_MAX
, max
= 0;
55 DWORD retval
, reply_size
;
56 char *send_data
, ip
[100], *hostname
= NULL
, rtt
[16];
59 ICMP_ECHO_REPLY
*reply
;
61 struct hostent
*remote_host
;
69 for (i
= 1; i
< argc
; i
++)
71 if (argv
[i
][0] == '-' || argv
[i
][0] == '/')
78 printf( "Missing value for option %s\n", argv
[i
] );
84 printf("Bad value for option -n, valid range is from 1 to 4294967295.\n");
91 printf( "Missing value for option %s\n", argv
[i
] );
97 printf("Bad value for option -w.\n");
104 printf( "Missing value for option %s\n", argv
[i
] );
110 printf("Bad value for option -l.\n");
119 WINE_FIXME( "this command currently only supports the -n, -w and -l parameters.\n" );
127 printf( "Bad argument %s\n", argv
[i
] );
136 printf("Pass a host name.\n");
140 res
= WSAStartup(MAKEWORD(2, 2), &wsa
);
143 printf("WSAStartup failed: %d\n", res
);
147 remote_host
= gethostbyname(hostname
);
148 if (remote_host
== NULL
)
150 printf("Ping request could not find host %s. Please check the name and try again.\n",
155 addr
.s_addr
= *(u_long
*) remote_host
->h_addr_list
[0];
156 strcpy(ip
, inet_ntoa(addr
));
157 ipaddr
= inet_addr(ip
);
158 if (ipaddr
== INADDR_NONE
)
160 printf("Could not get IP address of host %s.", hostname
);
164 icmp_file
= IcmpCreateFile();
166 send_data
= calloc(1, l
);
167 reply_size
= sizeof(ICMP_ECHO_REPLY
) + l
+ 8;
168 /* The buffer has to hold 8 more bytes of data (the size of an ICMP error message). */
169 reply_buffer
= malloc(reply_size
);
170 if (reply_buffer
== NULL
)
172 printf("Unable to allocate memory to reply buffer.\n");
176 printf("Pinging %s [%s] with %d bytes of data:\n", hostname
, ip
, l
);
177 for (i
= 0; i
< n
; i
++)
180 retval
= IcmpSendEcho(icmp_file
, ipaddr
, send_data
, l
,
181 NULL
, reply_buffer
, reply_size
, w
);
184 reply
= (ICMP_ECHO_REPLY
*) reply_buffer
;
185 if (reply
->RoundTripTime
>= 1)
186 sprintf(rtt
, "=%ld", reply
->RoundTripTime
);
189 printf("Reply from %s: bytes=%d time%sms TTL=%d\n", ip
, l
,
190 rtt
, reply
->Options
.Ttl
);
191 if (reply
->RoundTripTime
> max
)
192 max
= reply
->RoundTripTime
;
193 if (reply
->RoundTripTime
< min
)
194 min
= reply
->RoundTripTime
;
195 avg
+= reply
->RoundTripTime
;
200 if (GetLastError() == IP_REQ_TIMED_OUT
)
201 puts("Request timed out.");
203 puts("PING: transmit failed. General failure.");
206 if (i
< n
- 1) Sleep(1000);
209 printf("\nPing statistics for %s\n", ip
);
210 printf("\tPackets: Sent = %d, Received = %d, Lost = %d (%.0f%% loss)\n",
211 n
, rec
, lost
, (float) lost
/ n
* 100);
215 printf("Approximate round trip times in milli-seconds:\n");
216 printf("\tMinimum = %dms, Maximum = %dms, Average = %.0fms\n",