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
23 #include "wine/port.h"
39 #include "wine/debug.h"
40 #include "wine/heap.h"
42 WINE_DEFAULT_DEBUG_CHANNEL(ping
);
44 static void usage(void)
46 printf("Usage: ping [-n count] [-w timeout] [-l buffer_length] target_name\n\n"
48 " -n Number of echo requests to send.\n"
49 " -w Timeout in milliseconds to wait for each reply.\n"
50 " -l Length of send buffer.\n");
53 int main(int argc
, char** argv
)
55 unsigned int n
= 4, i
= 0, w
= 4000, l
= 32;
57 int rec
= 0, lost
= 0, min
= INT_MAX
, max
= 0;
61 DWORD retval
, reply_size
;
62 char *send_data
, ip
[100], *hostname
, rtt
[16];
65 ICMP_ECHO_REPLY
*reply
;
67 struct hostent
*remote_host
;
75 while ((optc
= getopt( argc
, argv
, "n:w:l:tal:fi:v:r:s:j:k:" )) != -1)
83 printf("Bad value for option -n, valid range is from 1 to 4294967295.\n");
91 printf("Bad value for option -w.\n");
99 printf("Bad value for option -l.\n");
108 WINE_FIXME( "this command currently only supports the -n, -w and -l parameters.\n" );
113 if (argv
[optind
] != NULL
)
114 hostname
= argv
[optind
];
117 printf("Pass a host name.\n");
121 res
= WSAStartup(MAKEWORD(2, 2), &wsa
);
124 printf("WSAStartup failed: %d\n", res
);
128 remote_host
= gethostbyname(hostname
);
129 if (remote_host
== NULL
)
131 printf("Ping request could not find host %s. Please check the name and try again.\n",
136 addr
.s_addr
= *(u_long
*) remote_host
->h_addr_list
[0];
137 strcpy(ip
, inet_ntoa(addr
));
138 ipaddr
= inet_addr(ip
);
139 if (ipaddr
== INADDR_NONE
)
141 printf("Could not get IP address of host %s.", hostname
);
145 icmp_file
= IcmpCreateFile();
147 send_data
= heap_alloc_zero(l
);
148 reply_size
= sizeof(ICMP_ECHO_REPLY
) + l
+ 8;
149 /* The buffer has to hold 8 more bytes of data (the size of an ICMP error message). */
150 reply_buffer
= heap_alloc(reply_size
);
151 if (reply_buffer
== NULL
)
153 printf("Unable to allocate memory to reply buffer.\n");
157 printf("Pinging %s [%s] with %d bytes of data:\n", hostname
, ip
, l
);
161 retval
= IcmpSendEcho(icmp_file
, ipaddr
, send_data
, l
,
162 NULL
, reply_buffer
, reply_size
, w
);
165 reply
= (ICMP_ECHO_REPLY
*) reply_buffer
;
166 if (reply
->RoundTripTime
>= 1)
167 sprintf(rtt
, "=%d", reply
->RoundTripTime
);
170 printf("Reply from %s: bytes=%d time%sms TTL=%d\n", ip
, l
,
171 rtt
, reply
->Options
.Ttl
);
172 if (reply
->RoundTripTime
> max
)
173 max
= reply
->RoundTripTime
;
174 if (reply
->RoundTripTime
< min
)
175 min
= reply
->RoundTripTime
;
176 avg
+= reply
->RoundTripTime
;
181 if (GetLastError() == IP_REQ_TIMED_OUT
)
182 puts("Request timed out.");
184 puts("PING: transmit failed. General failure.");
193 printf("\nPing statistics for %s\n", ip
);
194 printf("\tPackets: Sent = %d, Received = %d, Lost = %d (%.0f%% loss)\n",
195 n
, rec
, lost
, (float) lost
/ n
* 100);
199 printf("Approximate round trip times in milli-seconds:\n");
200 printf("\tMinimum = %dms, Maximum = %dms, Average = %.0fms\n",
204 heap_free(reply_buffer
);