xref: /iperf/src/iperf_error.c (revision 7bdd5b0e)
1 /*
2  * iperf, Copyright (c) 2014-2022, 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 [email protected].
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     }
76     va_end(argp);
77 }
78 
79 /* Do a printf to stderr or log file as appropriate, then exit. */
80 void
iperf_errexit(struct iperf_test * test,const char * format,...)81 iperf_errexit(struct iperf_test *test, const char *format, ...)
82 {
83     va_list argp;
84     char str[1000];
85     time_t now;
86     struct tm *ltm = NULL;
87     char *ct = NULL;
88 
89     /* Timestamp if requested */
90     if (test != NULL && test->timestamps) {
91 	time(&now);
92 	ltm = localtime(&now);
93 	strftime(iperf_timestrerr, sizeof(iperf_timestrerr), "%c ", ltm);
94 	ct = iperf_timestrerr;
95     }
96 
97     va_start(argp, format);
98     vsnprintf(str, sizeof(str), format, argp);
99     if (test != NULL && test->json_output && test->json_top != NULL) {
100 	cJSON_AddStringToObject(test->json_top, "error", str);
101 	iperf_json_finish(test);
102     } else
103 	if (test && test->outfile && test->outfile != stdout) {
104 	    if (ct) {
105 		fprintf(test->outfile, "%s", ct);
106 	    }
107 	    fprintf(test->outfile, "iperf3: %s\n", str);
108 	}
109 	else {
110 	    if (ct) {
111 		fprintf(stderr, "%s", ct);
112 	    }
113 	    fprintf(stderr, "iperf3: %s\n", str);
114 	}
115     va_end(argp);
116     if (test)
117         iperf_delete_pidfile(test);
118     exit(1);
119 }
120 
121 int i_errno;
122 
123 char *
iperf_strerror(int int_errno)124 iperf_strerror(int int_errno)
125 {
126     static char errstr[256];
127     int len, perr, herr;
128     perr = herr = 0;
129 
130     len = sizeof(errstr);
131     memset(errstr, 0, len);
132 
133     switch (int_errno) {
134         case IENONE:
135             snprintf(errstr, len, "no error");
136             break;
137         case IESERVCLIENT:
138             snprintf(errstr, len, "cannot be both server and client");
139             break;
140         case IENOROLE:
141             snprintf(errstr, len, "must either be a client (-c) or server (-s)");
142             break;
143         case IESERVERONLY:
144             snprintf(errstr, len, "some option you are trying to set is server only");
145             break;
146         case IECLIENTONLY:
147             snprintf(errstr, len, "some option you are trying to set is client only");
148             break;
149         case IEDURATION:
150             snprintf(errstr, len, "test duration too long (maximum = %d seconds)", MAX_TIME);
151             break;
152         case IENUMSTREAMS:
153             snprintf(errstr, len, "number of parallel streams too large (maximum = %d)", MAX_STREAMS);
154             break;
155         case IEBLOCKSIZE:
156             snprintf(errstr, len, "block size too large (maximum = %d bytes)", MAX_BLOCKSIZE);
157             break;
158         case IEBUFSIZE:
159             snprintf(errstr, len, "socket buffer size too large (maximum = %d bytes)", MAX_TCP_BUFFER);
160             break;
161         case IEINTERVAL:
162             snprintf(errstr, len, "invalid report interval (min = %g, max = %g seconds)", MIN_INTERVAL, MAX_INTERVAL);
163             break;
164     case IEBIND: /* UNUSED */
165             snprintf(errstr, len, "--bind must be specified to use --cport");
166             break;
167         case IEUDPBLOCKSIZE:
168             snprintf(errstr, len, "block size invalid (minimum = %d bytes, maximum = %d bytes)", MIN_UDP_BLOCKSIZE, MAX_UDP_BLOCKSIZE);
169             break;
170         case IEBADTOS:
171             snprintf(errstr, len, "bad TOS value (must be between 0 and 255 inclusive)");
172             break;
173         case IESETCLIENTAUTH:
174              snprintf(errstr, len, "you must specify a username, password, and path to a valid RSA public key");
175             break;
176         case IESETSERVERAUTH:
177              snprintf(errstr, len, "you must specify a path to a valid RSA private key and a user credential file");
178             break;
179 	case IEBADFORMAT:
180 	    snprintf(errstr, len, "bad format specifier (valid formats are in the set [kmgtKMGT])");
181 	    break;
182 	case IEBADPORT:
183 	    snprintf(errstr, len, "port number must be between 1 and 65535 inclusive");
184 	    break;
185         case IEMSS:
186             snprintf(errstr, len, "TCP MSS too large (maximum = %d bytes)", MAX_MSS);
187             break;
188         case IENOSENDFILE:
189             snprintf(errstr, len, "this OS does not support sendfile");
190             break;
191         case IEOMIT:
192             snprintf(errstr, len, "bogus value for --omit");
193             break;
194         case IEUNIMP:
195             snprintf(errstr, len, "an option you are trying to set is not implemented yet");
196             break;
197         case IEFILE:
198             snprintf(errstr, len, "unable to open -F file");
199             perr = 1;
200             break;
201         case IEBURST:
202             snprintf(errstr, len, "invalid burst count (maximum = %d)", MAX_BURST);
203             break;
204         case IEENDCONDITIONS:
205             snprintf(errstr, len, "only one test end condition (-t, -n, -k) may be specified");
206             break;
207 	case IELOGFILE:
208 	    snprintf(errstr, len, "unable to open log file");
209 	    perr = 1;
210 	    break;
211 	case IENOSCTP:
212 	    snprintf(errstr, len, "no SCTP support available");
213 	    break;
214         case IENEWTEST:
215             snprintf(errstr, len, "unable to create a new test");
216             perr = 1;
217             break;
218         case IEINITTEST:
219             snprintf(errstr, len, "test initialization failed");
220             perr = 1;
221             break;
222         case IEAUTHTEST:
223             snprintf(errstr, len, "test authorization failed");
224             break;
225         case IELISTEN:
226             snprintf(errstr, len, "unable to start listener for connections");
227 	    herr = 1;
228             perr = 1;
229             break;
230         case IECONNECT:
231             snprintf(errstr, len, "unable to connect to server");
232             perr = 1;
233 	    herr = 1;
234             break;
235         case IEACCEPT:
236             snprintf(errstr, len, "unable to accept connection from client");
237             herr = 1;
238             perr = 1;
239             break;
240         case IESENDCOOKIE:
241             snprintf(errstr, len, "unable to send cookie to server");
242             perr = 1;
243             break;
244         case IERECVCOOKIE:
245             snprintf(errstr, len, "unable to receive cookie at server");
246             perr = 1;
247             break;
248         case IECTRLWRITE:
249             snprintf(errstr, len, "unable to write to the control socket");
250             perr = 1;
251             break;
252         case IECTRLREAD:
253             snprintf(errstr, len, "unable to read from the control socket");
254             perr = 1;
255             break;
256         case IECTRLCLOSE:
257             snprintf(errstr, len, "control socket has closed unexpectedly");
258             break;
259         case IEMESSAGE:
260             snprintf(errstr, len, "received an unknown control message");
261             break;
262         case IESENDMESSAGE:
263             snprintf(errstr, len, "unable to send control message");
264             perr = 1;
265             break;
266         case IERECVMESSAGE:
267             snprintf(errstr, len, "unable to receive control message");
268             perr = 1;
269             break;
270         case IESENDPARAMS:
271             snprintf(errstr, len, "unable to send parameters to server");
272             perr = 1;
273             break;
274         case IERECVPARAMS:
275             snprintf(errstr, len, "unable to receive parameters from client");
276             perr = 1;
277             break;
278         case IEPACKAGERESULTS:
279             snprintf(errstr, len, "unable to package results");
280             perr = 1;
281             break;
282         case IESENDRESULTS:
283             snprintf(errstr, len, "unable to send results");
284             perr = 1;
285             break;
286         case IERECVRESULTS:
287             snprintf(errstr, len, "unable to receive results");
288             perr = 1;
289             break;
290         case IESELECT:
291             snprintf(errstr, len, "select failed");
292             perr = 1;
293             break;
294         case IECLIENTTERM:
295             snprintf(errstr, len, "the client has terminated");
296             break;
297         case IESERVERTERM:
298             snprintf(errstr, len, "the server has terminated");
299             break;
300         case IEACCESSDENIED:
301             snprintf(errstr, len, "the server is busy running a test. try again later");
302             break;
303         case IESETNODELAY:
304             snprintf(errstr, len, "unable to set TCP/SCTP NODELAY");
305             perr = 1;
306             break;
307         case IESETMSS:
308             snprintf(errstr, len, "unable to set TCP/SCTP MSS");
309             perr = 1;
310             break;
311         case IESETBUF:
312             snprintf(errstr, len, "unable to set socket buffer size");
313             perr = 1;
314             break;
315         case IESETTOS:
316             snprintf(errstr, len, "unable to set IP TOS");
317             perr = 1;
318             break;
319         case IESETCOS:
320             snprintf(errstr, len, "unable to set IPv6 traffic class");
321             perr = 1;
322             break;
323         case IESETFLOW:
324             snprintf(errstr, len, "unable to set IPv6 flow label");
325             break;
326         case IEREUSEADDR:
327             snprintf(errstr, len, "unable to reuse address on socket");
328             perr = 1;
329             break;
330         case IENONBLOCKING:
331             snprintf(errstr, len, "unable to set socket to non-blocking");
332             perr = 1;
333             break;
334         case IESETWINDOWSIZE:
335             snprintf(errstr, len, "unable to set socket window size");
336             perr = 1;
337             break;
338         case IEPROTOCOL:
339             snprintf(errstr, len, "protocol does not exist");
340             break;
341         case IEAFFINITY:
342             snprintf(errstr, len, "unable to set CPU affinity");
343             perr = 1;
344             break;
345         case IERCVTIMEOUT:
346             snprintf(errstr, len, "receive timeout value is incorrect or not in range");
347             perr = 1;
348             break;
349         case IESNDTIMEOUT:
350             snprintf(errstr, len, "send timeout value is incorrect or not in range");
351             perr = 1;
352             break;
353         case IERVRSONLYRCVTIMEOUT:
354             snprintf(errstr, len, "client receive timeout is valid only in receiving mode");
355             perr = 1;
356             break;
357 	case IEDAEMON:
358 	    snprintf(errstr, len, "unable to become a daemon");
359 	    perr = 1;
360 	    break;
361         case IECREATESTREAM:
362             snprintf(errstr, len, "unable to create a new stream");
363             herr = 1;
364             perr = 1;
365             break;
366         case IEINITSTREAM:
367             snprintf(errstr, len, "unable to initialize stream");
368             herr = 1;
369             perr = 1;
370             break;
371         case IESTREAMLISTEN:
372             snprintf(errstr, len, "unable to start stream listener");
373 	    herr = 1;
374             perr = 1;
375             break;
376         case IESTREAMCONNECT:
377             snprintf(errstr, len, "unable to connect stream");
378             herr = 1;
379             perr = 1;
380             break;
381         case IESTREAMACCEPT:
382             snprintf(errstr, len, "unable to accept stream connection");
383             perr = 1;
384             break;
385         case IESTREAMWRITE:
386             snprintf(errstr, len, "unable to write to stream socket");
387             perr = 1;
388             break;
389         case IESTREAMREAD:
390             snprintf(errstr, len, "unable to read from stream socket");
391             perr = 1;
392             break;
393         case IESTREAMCLOSE:
394             snprintf(errstr, len, "stream socket has closed unexpectedly");
395             break;
396         case IESTREAMID:
397             snprintf(errstr, len, "stream has an invalid id");
398             break;
399         case IENEWTIMER:
400             snprintf(errstr, len, "unable to create new timer");
401             perr = 1;
402             break;
403         case IEUPDATETIMER:
404             snprintf(errstr, len, "unable to update timer");
405             perr = 1;
406             break;
407         case IESETCONGESTION:
408             snprintf(errstr, len, "unable to set TCP_CONGESTION: "
409                                   "Supplied congestion control algorithm not supported on this host");
410             break;
411 	case IEPIDFILE:
412             snprintf(errstr, len, "unable to write PID file");
413             perr = 1;
414             break;
415 	case IEV6ONLY:
416 	    snprintf(errstr, len, "Unable to set/reset IPV6_V6ONLY");
417 	    perr = 1;
418 	    break;
419         case IESETSCTPDISABLEFRAG:
420             snprintf(errstr, len, "unable to set SCTP_DISABLE_FRAGMENTS");
421             perr = 1;
422             break;
423         case IESETSCTPNSTREAM:
424             snprintf(errstr, len, "unable to set SCTP_INIT num of SCTP streams\n");
425             perr = 1;
426             break;
427 	case IESETPACING:
428 	    snprintf(errstr, len, "unable to set socket pacing");
429 	    perr = 1;
430 	    break;
431 	case IESETBUF2:
432 	    snprintf(errstr, len, "socket buffer size not set correctly");
433 	    break;
434 	case IEREVERSEBIDIR:
435 	    snprintf(errstr, len, "cannot be both reverse and bidirectional");
436             break;
437 	case IETOTALRATE:
438 	    snprintf(errstr, len, "total required bandwidth is larger than server limit");
439             break;
440     case IESKEWTHRESHOLD:
441 	    snprintf(errstr, len, "skew threshold must be a positive number");
442             break;
443 	case IEIDLETIMEOUT:
444 	    snprintf(errstr, len, "idle timeout parameter is not positive or larger than allowed limit");
445             break;
446 	case IEBINDDEV:
447 	    snprintf(errstr, len, "Unable to bind-to-device (check perror, maybe permissions?)");
448             break;
449     case IEBINDDEVNOSUPPORT:
450 	    snprintf(errstr, len, "`<ip>%%<dev>` is not supported as system does not support bind to device");
451             break;
452     case IEHOSTDEV:
453 	    snprintf(errstr, len, "host device name (ip%%<dev>) is supported (and required) only for IPv6 link-local address");
454             break;
455 	case IENOMSG:
456 	    snprintf(errstr, len, "idle timeout for receiving data");
457             break;
458     case IESETDONTFRAGMENT:
459 	    snprintf(errstr, len, "unable to set IP Do-Not-Fragment flag");
460             break;
461         case IESETUSERTIMEOUT:
462             snprintf(errstr, len, "unable to set TCP/SCTP MSS");
463             perr = 1;
464             break;
465 	default:
466 	    snprintf(errstr, len, "int_errno=%d", int_errno);
467 	    perr = 1;
468 	    break;
469     }
470 
471     /* Append the result of strerror() or gai_strerror() if appropriate */
472     if (herr || perr)
473         strncat(errstr, ": ", len - strlen(errstr) - 1);
474     if (errno && perr)
475         strncat(errstr, strerror(errno), len - strlen(errstr) - 1);
476     else if (herr && gerror) {
477         strncat(errstr, gai_strerror(gerror), len - strlen(errstr) - 1);
478 	gerror = 0;
479     }
480 
481     return errstr;
482 }
483