1 /*
2 * iperf, Copyright (c) 2014-2020, The Regents of the University of
3 * California, through Lawrence Berkeley National Laboratory (subject
4 * to receipt of any required approvals from the U.S. Dept. of
5 * Energy). All rights reserved.
6 *
7 * If you have questions about your rights to use or distribute this
8 * software, please contact Berkeley Lab's Technology Transfer
9 * Department at TTD@lbl.gov.
10 *
11 * NOTICE. This software is owned by the U.S. Department of Energy.
12 * As such, the U.S. Government has been granted for itself and others
13 * acting on its behalf a paid-up, nonexclusive, irrevocable,
14 * worldwide license in the Software to reproduce, prepare derivative
15 * works, and perform publicly and display publicly. Beginning five
16 * (5) years after the date permission to assert copyright is obtained
17 * from the U.S. Department of Energy, and subject to any subsequent
18 * five (5) year renewals, the U.S. Government is granted for itself
19 * and others acting on its behalf a paid-up, nonexclusive,
20 * irrevocable, worldwide license in the Software to reproduce,
21 * prepare derivative works, distribute copies to the public, perform
22 * publicly and display publicly, and to permit others to do so.
23 *
24 * This code is distributed under a BSD style license, see the LICENSE
25 * file for complete information.
26 */
27 #include <stdio.h>
28 #include <errno.h>
29 #include <netdb.h>
30 #include <string.h>
31 #include <stdlib.h>
32 #include <stdarg.h>
33 #include "iperf.h"
34 #include "iperf_api.h"
35
36 int gerror;
37
38 char iperf_timestrerr[100];
39
40 /* Do a printf to stderr. */
41 void
iperf_err(struct iperf_test * test,const char * format,...)42 iperf_err(struct iperf_test *test, const char *format, ...)
43 {
44 va_list argp;
45 char str[1000];
46 time_t now;
47 struct tm *ltm = NULL;
48 char *ct = NULL;
49
50 /* Timestamp if requested */
51 if (test != NULL && test->timestamps) {
52 time(&now);
53 ltm = localtime(&now);
54 strftime(iperf_timestrerr, sizeof(iperf_timestrerr), test->timestamp_format, ltm);
55 ct = iperf_timestrerr;
56 }
57
58 va_start(argp, format);
59 vsnprintf(str, sizeof(str), format, argp);
60 if (test != NULL && test->json_output && test->json_top != NULL)
61 cJSON_AddStringToObject(test->json_top, "error", str);
62 else
63 if (test && test->outfile && test->outfile != stdout) {
64 if (ct) {
65 fprintf(test->outfile, "%s", ct);
66 }
67 fprintf(test->outfile, "iperf3: %s\n", str);
68 }
69 else {
70 if (ct) {
71 fprintf(stderr, "%s", ct);
72 }
73 fprintf(stderr, "iperf3: %s\n", str);
74 }
75 va_end(argp);
76 }
77
78 /* Do a printf to stderr or log file as appropriate, then exit. */
79 void
iperf_errexit(struct iperf_test * test,const char * format,...)80 iperf_errexit(struct iperf_test *test, const char *format, ...)
81 {
82 va_list argp;
83 char str[1000];
84 time_t now;
85 struct tm *ltm = NULL;
86 char *ct = NULL;
87
88 /* Timestamp if requested */
89 if (test != NULL && test->timestamps) {
90 time(&now);
91 ltm = localtime(&now);
92 strftime(iperf_timestrerr, sizeof(iperf_timestrerr), "%c ", ltm);
93 ct = iperf_timestrerr;
94 }
95
96 va_start(argp, format);
97 vsnprintf(str, sizeof(str), format, argp);
98 if (test != NULL && test->json_output && test->json_top != NULL) {
99 cJSON_AddStringToObject(test->json_top, "error", str);
100 iperf_json_finish(test);
101 } else
102 if (test && test->outfile && test->outfile != stdout) {
103 if (ct) {
104 fprintf(test->outfile, "%s", ct);
105 }
106 fprintf(test->outfile, "iperf3: %s\n", str);
107 }
108 else {
109 if (ct) {
110 fprintf(stderr, "%s", ct);
111 }
112 fprintf(stderr, "iperf3: %s\n", str);
113 }
114 va_end(argp);
115 if (test)
116 iperf_delete_pidfile(test);
117 exit(1);
118 }
119
120 int i_errno;
121
122 char *
iperf_strerror(int int_errno)123 iperf_strerror(int int_errno)
124 {
125 static char errstr[256];
126 int len, perr, herr;
127 perr = herr = 0;
128
129 len = sizeof(errstr);
130 memset(errstr, 0, len);
131
132 switch (int_errno) {
133 case IENONE:
134 snprintf(errstr, len, "no error");
135 break;
136 case IESERVCLIENT:
137 snprintf(errstr, len, "cannot be both server and client");
138 break;
139 case IENOROLE:
140 snprintf(errstr, len, "must either be a client (-c) or server (-s)");
141 break;
142 case IESERVERONLY:
143 snprintf(errstr, len, "some option you are trying to set is server only");
144 break;
145 case IECLIENTONLY:
146 snprintf(errstr, len, "some option you are trying to set is client only");
147 break;
148 case IEDURATION:
149 snprintf(errstr, len, "test duration too long (maximum = %d seconds)", MAX_TIME);
150 break;
151 case IENUMSTREAMS:
152 snprintf(errstr, len, "number of parallel streams too large (maximum = %d)", MAX_STREAMS);
153 break;
154 case IEBLOCKSIZE:
155 snprintf(errstr, len, "block size too large (maximum = %d bytes)", MAX_BLOCKSIZE);
156 break;
157 case IEBUFSIZE:
158 snprintf(errstr, len, "socket buffer size too large (maximum = %d bytes)", MAX_TCP_BUFFER);
159 break;
160 case IEINTERVAL:
161 snprintf(errstr, len, "invalid report interval (min = %g, max = %g seconds)", MIN_INTERVAL, MAX_INTERVAL);
162 break;
163 case IEBIND: /* UNUSED */
164 snprintf(errstr, len, "--bind must be specified to use --cport");
165 break;
166 case IEUDPBLOCKSIZE:
167 snprintf(errstr, len, "block size invalid (minimum = %d bytes, maximum = %d bytes)", MIN_UDP_BLOCKSIZE, MAX_UDP_BLOCKSIZE);
168 break;
169 case IEBADTOS:
170 snprintf(errstr, len, "bad TOS value (must be between 0 and 255 inclusive)");
171 break;
172 case IESETCLIENTAUTH:
173 snprintf(errstr, len, "you must specify a username, password, and path to a valid RSA public key");
174 break;
175 case IESETSERVERAUTH:
176 snprintf(errstr, len, "you must specify a path to a valid RSA private key and a user credential file");
177 break;
178 case IEBADFORMAT:
179 snprintf(errstr, len, "bad format specifier (valid formats are in the set [kmgtKMGT])");
180 break;
181 case IEBADPORT:
182 snprintf(errstr, len, "port number must be between 1 and 65535 inclusive");
183 break;
184 case IEMSS:
185 snprintf(errstr, len, "TCP MSS too large (maximum = %d bytes)", MAX_MSS);
186 break;
187 case IENOSENDFILE:
188 snprintf(errstr, len, "this OS does not support sendfile");
189 break;
190 case IEOMIT:
191 snprintf(errstr, len, "bogus value for --omit");
192 break;
193 case IEUNIMP:
194 snprintf(errstr, len, "an option you are trying to set is not implemented yet");
195 break;
196 case IEFILE:
197 snprintf(errstr, len, "unable to open -F file");
198 perr = 1;
199 break;
200 case IEBURST:
201 snprintf(errstr, len, "invalid burst count (maximum = %d)", MAX_BURST);
202 break;
203 case IEENDCONDITIONS:
204 snprintf(errstr, len, "only one test end condition (-t, -n, -k) may be specified");
205 break;
206 case IELOGFILE:
207 snprintf(errstr, len, "unable to open log file");
208 perr = 1;
209 break;
210 case IENOSCTP:
211 snprintf(errstr, len, "no SCTP support available");
212 break;
213 case IENEWTEST:
214 snprintf(errstr, len, "unable to create a new test");
215 perr = 1;
216 break;
217 case IEINITTEST:
218 snprintf(errstr, len, "test initialization failed");
219 perr = 1;
220 break;
221 case IEAUTHTEST:
222 snprintf(errstr, len, "test authorization failed");
223 break;
224 case IELISTEN:
225 snprintf(errstr, len, "unable to start listener for connections");
226 herr = 1;
227 perr = 1;
228 break;
229 case IECONNECT:
230 snprintf(errstr, len, "unable to connect to server");
231 perr = 1;
232 herr = 1;
233 break;
234 case IEACCEPT:
235 snprintf(errstr, len, "unable to accept connection from client");
236 herr = 1;
237 perr = 1;
238 break;
239 case IESENDCOOKIE:
240 snprintf(errstr, len, "unable to send cookie to server");
241 perr = 1;
242 break;
243 case IERECVCOOKIE:
244 snprintf(errstr, len, "unable to receive cookie at server");
245 perr = 1;
246 break;
247 case IECTRLWRITE:
248 snprintf(errstr, len, "unable to write to the control socket");
249 perr = 1;
250 break;
251 case IECTRLREAD:
252 snprintf(errstr, len, "unable to read from the control socket");
253 perr = 1;
254 break;
255 case IECTRLCLOSE:
256 snprintf(errstr, len, "control socket has closed unexpectedly");
257 break;
258 case IEMESSAGE:
259 snprintf(errstr, len, "received an unknown control message");
260 break;
261 case IESENDMESSAGE:
262 snprintf(errstr, len, "unable to send control message");
263 perr = 1;
264 break;
265 case IERECVMESSAGE:
266 snprintf(errstr, len, "unable to receive control message");
267 perr = 1;
268 break;
269 case IESENDPARAMS:
270 snprintf(errstr, len, "unable to send parameters to server");
271 perr = 1;
272 break;
273 case IERECVPARAMS:
274 snprintf(errstr, len, "unable to receive parameters from client");
275 perr = 1;
276 break;
277 case IEPACKAGERESULTS:
278 snprintf(errstr, len, "unable to package results");
279 perr = 1;
280 break;
281 case IESENDRESULTS:
282 snprintf(errstr, len, "unable to send results");
283 perr = 1;
284 break;
285 case IERECVRESULTS:
286 snprintf(errstr, len, "unable to receive results");
287 perr = 1;
288 break;
289 case IESELECT:
290 snprintf(errstr, len, "select failed");
291 perr = 1;
292 break;
293 case IECLIENTTERM:
294 snprintf(errstr, len, "the client has terminated");
295 break;
296 case IESERVERTERM:
297 snprintf(errstr, len, "the server has terminated");
298 break;
299 case IEACCESSDENIED:
300 snprintf(errstr, len, "the server is busy running a test. try again later");
301 break;
302 case IESETNODELAY:
303 snprintf(errstr, len, "unable to set TCP/SCTP NODELAY");
304 perr = 1;
305 break;
306 case IESETMSS:
307 snprintf(errstr, len, "unable to set TCP/SCTP MSS");
308 perr = 1;
309 break;
310 case IESETBUF:
311 snprintf(errstr, len, "unable to set socket buffer size");
312 perr = 1;
313 break;
314 case IESETTOS:
315 snprintf(errstr, len, "unable to set IP TOS");
316 perr = 1;
317 break;
318 case IESETCOS:
319 snprintf(errstr, len, "unable to set IPv6 traffic class");
320 perr = 1;
321 break;
322 case IESETFLOW:
323 snprintf(errstr, len, "unable to set IPv6 flow label");
324 break;
325 case IEREUSEADDR:
326 snprintf(errstr, len, "unable to reuse address on socket");
327 perr = 1;
328 break;
329 case IENONBLOCKING:
330 snprintf(errstr, len, "unable to set socket to non-blocking");
331 perr = 1;
332 break;
333 case IESETWINDOWSIZE:
334 snprintf(errstr, len, "unable to set socket window size");
335 perr = 1;
336 break;
337 case IEPROTOCOL:
338 snprintf(errstr, len, "protocol does not exist");
339 break;
340 case IEAFFINITY:
341 snprintf(errstr, len, "unable to set CPU affinity");
342 perr = 1;
343 break;
344 case IEDAEMON:
345 snprintf(errstr, len, "unable to become a daemon");
346 perr = 1;
347 break;
348 case IECREATESTREAM:
349 snprintf(errstr, len, "unable to create a new stream");
350 herr = 1;
351 perr = 1;
352 break;
353 case IEINITSTREAM:
354 snprintf(errstr, len, "unable to initialize stream");
355 herr = 1;
356 perr = 1;
357 break;
358 case IESTREAMLISTEN:
359 snprintf(errstr, len, "unable to start stream listener");
360 herr = 1;
361 perr = 1;
362 break;
363 case IESTREAMCONNECT:
364 snprintf(errstr, len, "unable to connect stream");
365 herr = 1;
366 perr = 1;
367 break;
368 case IESTREAMACCEPT:
369 snprintf(errstr, len, "unable to accept stream connection");
370 perr = 1;
371 break;
372 case IESTREAMWRITE:
373 snprintf(errstr, len, "unable to write to stream socket");
374 perr = 1;
375 break;
376 case IESTREAMREAD:
377 snprintf(errstr, len, "unable to read from stream socket");
378 perr = 1;
379 break;
380 case IESTREAMCLOSE:
381 snprintf(errstr, len, "stream socket has closed unexpectedly");
382 break;
383 case IESTREAMID:
384 snprintf(errstr, len, "stream has an invalid id");
385 break;
386 case IENEWTIMER:
387 snprintf(errstr, len, "unable to create new timer");
388 perr = 1;
389 break;
390 case IEUPDATETIMER:
391 snprintf(errstr, len, "unable to update timer");
392 perr = 1;
393 break;
394 case IESETCONGESTION:
395 snprintf(errstr, len, "unable to set TCP_CONGESTION: "
396 "Supplied congestion control algorithm not supported on this host");
397 break;
398 case IEPIDFILE:
399 snprintf(errstr, len, "unable to write PID file");
400 perr = 1;
401 break;
402 case IEV6ONLY:
403 snprintf(errstr, len, "Unable to set/reset IPV6_V6ONLY");
404 perr = 1;
405 break;
406 case IESETSCTPDISABLEFRAG:
407 snprintf(errstr, len, "unable to set SCTP_DISABLE_FRAGMENTS");
408 perr = 1;
409 break;
410 case IESETSCTPNSTREAM:
411 snprintf(errstr, len, "unable to set SCTP_INIT num of SCTP streams\n");
412 perr = 1;
413 break;
414 case IESETPACING:
415 snprintf(errstr, len, "unable to set socket pacing");
416 perr = 1;
417 break;
418 case IESETBUF2:
419 snprintf(errstr, len, "socket buffer size not set correctly");
420 break;
421 case IEREVERSEBIDIR:
422 snprintf(errstr, len, "cannot be both reverse and bidirectional");
423 break;
424 case IETOTALRATE:
425 snprintf(errstr, len, "total required bandwidth is larger than server limit");
426 break;
427 default:
428 snprintf(errstr, len, "int_errno=%d", int_errno);
429 perr = 1;
430 break;
431 }
432
433 /* Append the result of strerror() or gai_strerror() if appropriate */
434 if (herr || perr)
435 strncat(errstr, ": ", len - strlen(errstr) - 1);
436 if (errno && perr)
437 strncat(errstr, strerror(errno), len - strlen(errstr) - 1);
438 else if (herr && gerror) {
439 strncat(errstr, gai_strerror(gerror), len - strlen(errstr) - 1);
440 gerror = 0;
441 }
442
443 return errstr;
444 }
445