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