comdlg32/tests: Avoid "misleading indentation" warnings.
[wine.git] / programs / ping / ping_main.c
blob51246e3f5bfa8b2dade68dbf901bc152458d3f83
1 /*
2 * ping program
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
22 #include "winsock2.h"
23 #include "ws2tcpip.h"
24 #include "iphlpapi.h"
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <icmpapi.h>
30 #include <limits.h>
32 #include <windows.h>
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"
42 "Options:\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;
51 int res;
52 int rec = 0, lost = 0, min = INT_MAX, max = 0;
53 WSADATA wsa;
54 HANDLE icmp_file;
55 unsigned long ipaddr;
56 DWORD retval, reply_size;
57 char *send_data, ip[100], *hostname = NULL, rtt[16];
58 void *reply_buffer;
59 struct in_addr addr;
60 ICMP_ECHO_REPLY *reply;
61 float avg = 0;
62 struct hostent *remote_host;
64 if (argc == 1)
66 usage();
67 exit(1);
70 for (i = 1; i < argc; i++)
72 if (argv[i][0] == '-' || argv[i][0] == '/')
74 switch (argv[i][1])
76 case 'n':
77 if (i == argc - 1)
79 printf( "Missing value for option %s\n", argv[i] );
80 exit(1);
82 n = atoi(argv[++i]);
83 if (n == 0)
85 printf("Bad value for option -n, valid range is from 1 to 4294967295.\n");
86 exit(1);
88 break;
89 case 'w':
90 if (i == argc - 1)
92 printf( "Missing value for option %s\n", argv[i] );
93 exit(1);
95 w = atoi(argv[++i]);
96 if (w == 0)
98 printf("Bad value for option -w.\n");
99 exit(1);
101 break;
102 case 'l':
103 if (i == argc - 1)
105 printf( "Missing value for option %s\n", argv[i] );
106 exit(1);
108 l = atoi(argv[++i]);
109 if (l == 0)
111 printf("Bad value for option -l.\n");
112 exit(1);
114 break;
115 case '?':
116 usage();
117 exit(1);
118 default:
119 usage();
120 WINE_FIXME( "this command currently only supports the -n, -w and -l parameters.\n" );
121 exit(1);
124 else
126 if (hostname)
128 printf( "Bad argument %s\n", argv[i] );
129 exit(1);
131 hostname = argv[i];
135 if (!hostname)
137 printf("Pass a host name.\n");
138 return 1;
141 res = WSAStartup(MAKEWORD(2, 2), &wsa);
142 if (res != 0)
144 printf("WSAStartup failed: %d\n", res);
145 return 1;
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",
152 hostname);
153 return 1;
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);
162 return 1;
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");
174 return 1;
177 printf("Pinging %s [%s] with %d bytes of data:\n", hostname, ip, l);
178 for (i = 0; i < n; i++)
180 SetLastError(0);
181 retval = IcmpSendEcho(icmp_file, ipaddr, send_data, l,
182 NULL, reply_buffer, reply_size, w);
183 if (retval != 0)
185 reply = (ICMP_ECHO_REPLY *) reply_buffer;
186 if (reply->RoundTripTime >= 1)
187 sprintf(rtt, "=%d", reply->RoundTripTime);
188 else
189 strcpy(rtt, "<1");
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;
197 rec++;
199 else
201 if (GetLastError() == IP_REQ_TIMED_OUT)
202 puts("Request timed out.");
203 else
204 puts("PING: transmit failed. General failure.");
205 lost++;
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);
213 if (rec != 0)
215 avg /= rec;
216 printf("Approximate round trip times in milli-seconds:\n");
217 printf("\tMinimum = %dms, Maximum = %dms, Average = %.0fms\n",
218 min, max, avg);
221 heap_free(reply_buffer);
222 return 0;