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