1 /*
2  * iperf, Copyright (c) 2014-2021, 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 IERCVTIMEOUT:
345             snprintf(errstr, len, "receive timeout value is incorrect or not in range");
346             perr = 1;
347             break;
348         case IERVRSONLYRCVTIMEOUT:
349             snprintf(errstr, len, "client receive timeout is valid only in receiving mode");
350             perr = 1;
351             break;
352 	case IEDAEMON:
353 	    snprintf(errstr, len, "unable to become a daemon");
354 	    perr = 1;
355 	    break;
356         case IECREATESTREAM:
357             snprintf(errstr, len, "unable to create a new stream");
358             herr = 1;
359             perr = 1;
360             break;
361         case IEINITSTREAM:
362             snprintf(errstr, len, "unable to initialize stream");
363             herr = 1;
364             perr = 1;
365             break;
366         case IESTREAMLISTEN:
367             snprintf(errstr, len, "unable to start stream listener");
368 	    herr = 1;
369             perr = 1;
370             break;
371         case IESTREAMCONNECT:
372             snprintf(errstr, len, "unable to connect stream");
373             herr = 1;
374             perr = 1;
375             break;
376         case IESTREAMACCEPT:
377             snprintf(errstr, len, "unable to accept stream connection");
378             perr = 1;
379             break;
380         case IESTREAMWRITE:
381             snprintf(errstr, len, "unable to write to stream socket");
382             perr = 1;
383             break;
384         case IESTREAMREAD:
385             snprintf(errstr, len, "unable to read from stream socket");
386             perr = 1;
387             break;
388         case IESTREAMCLOSE:
389             snprintf(errstr, len, "stream socket has closed unexpectedly");
390             break;
391         case IESTREAMID:
392             snprintf(errstr, len, "stream has an invalid id");
393             break;
394         case IENEWTIMER:
395             snprintf(errstr, len, "unable to create new timer");
396             perr = 1;
397             break;
398         case IEUPDATETIMER:
399             snprintf(errstr, len, "unable to update timer");
400             perr = 1;
401             break;
402         case IESETCONGESTION:
403             snprintf(errstr, len, "unable to set TCP_CONGESTION: "
404                                   "Supplied congestion control algorithm not supported on this host");
405             break;
406 	case IEPIDFILE:
407             snprintf(errstr, len, "unable to write PID file");
408             perr = 1;
409             break;
410 	case IEV6ONLY:
411 	    snprintf(errstr, len, "Unable to set/reset IPV6_V6ONLY");
412 	    perr = 1;
413 	    break;
414         case IESETSCTPDISABLEFRAG:
415             snprintf(errstr, len, "unable to set SCTP_DISABLE_FRAGMENTS");
416             perr = 1;
417             break;
418         case IESETSCTPNSTREAM:
419             snprintf(errstr, len, "unable to set SCTP_INIT num of SCTP streams\n");
420             perr = 1;
421             break;
422 	case IESETPACING:
423 	    snprintf(errstr, len, "unable to set socket pacing");
424 	    perr = 1;
425 	    break;
426 	case IESETBUF2:
427 	    snprintf(errstr, len, "socket buffer size not set correctly");
428 	    break;
429 	case IEREVERSEBIDIR:
430 	    snprintf(errstr, len, "cannot be both reverse and bidirectional");
431             break;
432 	case IETOTALRATE:
433 	    snprintf(errstr, len, "total required bandwidth is larger than server limit");
434             break;
435     case IESKEWTHRESHOLD:
436 	    snprintf(errstr, len, "skew threshold must be a positive number");
437             break;
438 	case IEIDLETIMEOUT:
439 	    snprintf(errstr, len, "idle timeout parameter is not positive or larget then allowed limit");
440             break;
441 	case IENOMSG:
442 	    snprintf(errstr, len, "idle timeout for receiving data");
443             break;
444     case IESETDONTFRAGMENT:
445 	    snprintf(errstr, len, "unable to set IP Do-Not-Fragment flag");
446             break;
447 	default:
448 	    snprintf(errstr, len, "int_errno=%d", int_errno);
449 	    perr = 1;
450 	    break;
451     }
452 
453     /* Append the result of strerror() or gai_strerror() if appropriate */
454     if (herr || perr)
455         strncat(errstr, ": ", len - strlen(errstr) - 1);
456     if (errno && perr)
457         strncat(errstr, strerror(errno), len - strlen(errstr) - 1);
458     else if (herr && gerror) {
459         strncat(errstr, gai_strerror(gerror), len - strlen(errstr) - 1);
460 	gerror = 0;
461     }
462 
463     return errstr;
464 }
465