1 /*
2 * iperf, Copyright (c) 2014-2019, 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 /* Do a printf to stderr. */
39 void
iperf_err(struct iperf_test * test,const char * format,...)40 iperf_err(struct iperf_test *test, const char *format, ...)
41 {
42 va_list argp;
43 char str[1000];
44
45 va_start(argp, format);
46 vsnprintf(str, sizeof(str), format, argp);
47 if (test != NULL && test->json_output && test->json_top != NULL)
48 cJSON_AddStringToObject(test->json_top, "error", str);
49 else
50 if (test && test->outfile && test->outfile != stdout) {
51 fprintf(test->outfile, "iperf3: %s\n", str);
52 }
53 else {
54 fprintf(stderr, "iperf3: %s\n", str);
55 }
56 va_end(argp);
57 }
58
59 /* Do a printf to stderr or log file as appropriate, then exit. */
60 void
iperf_errexit(struct iperf_test * test,const char * format,...)61 iperf_errexit(struct iperf_test *test, const char *format, ...)
62 {
63 va_list argp;
64 char str[1000];
65
66 va_start(argp, format);
67 vsnprintf(str, sizeof(str), format, argp);
68 if (test != NULL && test->json_output && test->json_top != NULL) {
69 cJSON_AddStringToObject(test->json_top, "error", str);
70 iperf_json_finish(test);
71 } else
72 if (test && test->outfile && test->outfile != stdout) {
73 fprintf(test->outfile, "iperf3: %s\n", str);
74 }
75 else {
76 fprintf(stderr, "iperf3: %s\n", str);
77 }
78 va_end(argp);
79 if (test)
80 iperf_delete_pidfile(test);
81 exit(1);
82 }
83
84 int i_errno;
85
86 char *
iperf_strerror(int int_errno)87 iperf_strerror(int int_errno)
88 {
89 static char errstr[256];
90 int len, perr, herr;
91 perr = herr = 0;
92
93 len = sizeof(errstr);
94 memset(errstr, 0, len);
95
96 switch (int_errno) {
97 case IENONE:
98 snprintf(errstr, len, "no error");
99 break;
100 case IESERVCLIENT:
101 snprintf(errstr, len, "cannot be both server and client");
102 break;
103 case IENOROLE:
104 snprintf(errstr, len, "must either be a client (-c) or server (-s)");
105 break;
106 case IESERVERONLY:
107 snprintf(errstr, len, "some option you are trying to set is server only");
108 break;
109 case IECLIENTONLY:
110 snprintf(errstr, len, "some option you are trying to set is client only");
111 break;
112 case IEDURATION:
113 snprintf(errstr, len, "test duration too long (maximum = %d seconds)", MAX_TIME);
114 break;
115 case IENUMSTREAMS:
116 snprintf(errstr, len, "number of parallel streams too large (maximum = %d)", MAX_STREAMS);
117 break;
118 case IEBLOCKSIZE:
119 snprintf(errstr, len, "block size too large (maximum = %d bytes)", MAX_BLOCKSIZE);
120 break;
121 case IEBUFSIZE:
122 snprintf(errstr, len, "socket buffer size too large (maximum = %d bytes)", MAX_TCP_BUFFER);
123 break;
124 case IEINTERVAL:
125 snprintf(errstr, len, "invalid report interval (min = %g, max = %g seconds)", MIN_INTERVAL, MAX_INTERVAL);
126 break;
127 case IEBIND: /* UNUSED */
128 snprintf(errstr, len, "--bind must be specified to use --cport");
129 break;
130 case IEUDPBLOCKSIZE:
131 snprintf(errstr, len, "block size invalid (minimum = %d bytes, maximum = %d bytes)", MIN_UDP_BLOCKSIZE, MAX_UDP_BLOCKSIZE);
132 break;
133 case IEBADTOS:
134 snprintf(errstr, len, "bad TOS value (must be between 0 and 255 inclusive)");
135 break;
136 case IESETCLIENTAUTH:
137 snprintf(errstr, len, "you must specify username (max 20 chars), password (max 20 chars) and a path to a valid public rsa client to be used");
138 break;
139 case IESETSERVERAUTH:
140 snprintf(errstr, len, "you must specify path to a valid private rsa server to be used and a user credential file");
141 break;
142 case IEBADFORMAT:
143 snprintf(errstr, len, "bad format specifier (valid formats are in the set [kmgtKMGT])");
144 break;
145 case IEBADPORT:
146 snprintf(errstr, len, "port number must be between 1 and 65535 inclusive");
147 break;
148 case IEMSS:
149 snprintf(errstr, len, "TCP MSS too large (maximum = %d bytes)", MAX_MSS);
150 break;
151 case IENOSENDFILE:
152 snprintf(errstr, len, "this OS does not support sendfile");
153 break;
154 case IEOMIT:
155 snprintf(errstr, len, "bogus value for --omit");
156 break;
157 case IEUNIMP:
158 snprintf(errstr, len, "an option you are trying to set is not implemented yet");
159 break;
160 case IEFILE:
161 snprintf(errstr, len, "unable to open -F file");
162 perr = 1;
163 break;
164 case IEBURST:
165 snprintf(errstr, len, "invalid burst count (maximum = %d)", MAX_BURST);
166 break;
167 case IEENDCONDITIONS:
168 snprintf(errstr, len, "only one test end condition (-t, -n, -k) may be specified");
169 break;
170 case IELOGFILE:
171 snprintf(errstr, len, "unable to open log file");
172 perr = 1;
173 break;
174 case IENOSCTP:
175 snprintf(errstr, len, "no SCTP support available");
176 break;
177 case IENEWTEST:
178 snprintf(errstr, len, "unable to create a new test");
179 perr = 1;
180 break;
181 case IEINITTEST:
182 snprintf(errstr, len, "test initialization failed");
183 perr = 1;
184 break;
185 case IEAUTHTEST:
186 snprintf(errstr, len, "test authorization failed");
187 break;
188 case IELISTEN:
189 snprintf(errstr, len, "unable to start listener for connections");
190 herr = 1;
191 perr = 1;
192 break;
193 case IECONNECT:
194 snprintf(errstr, len, "unable to connect to server");
195 perr = 1;
196 herr = 1;
197 break;
198 case IEACCEPT:
199 snprintf(errstr, len, "unable to accept connection from client");
200 herr = 1;
201 perr = 1;
202 break;
203 case IESENDCOOKIE:
204 snprintf(errstr, len, "unable to send cookie to server");
205 perr = 1;
206 break;
207 case IERECVCOOKIE:
208 snprintf(errstr, len, "unable to receive cookie at server");
209 perr = 1;
210 break;
211 case IECTRLWRITE:
212 snprintf(errstr, len, "unable to write to the control socket");
213 perr = 1;
214 break;
215 case IECTRLREAD:
216 snprintf(errstr, len, "unable to read from the control socket");
217 perr = 1;
218 break;
219 case IECTRLCLOSE:
220 snprintf(errstr, len, "control socket has closed unexpectedly");
221 break;
222 case IEMESSAGE:
223 snprintf(errstr, len, "received an unknown control message");
224 break;
225 case IESENDMESSAGE:
226 snprintf(errstr, len, "unable to send control message");
227 perr = 1;
228 break;
229 case IERECVMESSAGE:
230 snprintf(errstr, len, "unable to receive control message");
231 perr = 1;
232 break;
233 case IESENDPARAMS:
234 snprintf(errstr, len, "unable to send parameters to server");
235 perr = 1;
236 break;
237 case IERECVPARAMS:
238 snprintf(errstr, len, "unable to receive parameters from client");
239 perr = 1;
240 break;
241 case IEPACKAGERESULTS:
242 snprintf(errstr, len, "unable to package results");
243 perr = 1;
244 break;
245 case IESENDRESULTS:
246 snprintf(errstr, len, "unable to send results");
247 perr = 1;
248 break;
249 case IERECVRESULTS:
250 snprintf(errstr, len, "unable to receive results");
251 perr = 1;
252 break;
253 case IESELECT:
254 snprintf(errstr, len, "select failed");
255 perr = 1;
256 break;
257 case IECLIENTTERM:
258 snprintf(errstr, len, "the client has terminated");
259 break;
260 case IESERVERTERM:
261 snprintf(errstr, len, "the server has terminated");
262 break;
263 case IEACCESSDENIED:
264 snprintf(errstr, len, "the server is busy running a test. try again later");
265 break;
266 case IESETNODELAY:
267 snprintf(errstr, len, "unable to set TCP/SCTP NODELAY");
268 perr = 1;
269 break;
270 case IESETMSS:
271 snprintf(errstr, len, "unable to set TCP/SCTP MSS");
272 perr = 1;
273 break;
274 case IESETBUF:
275 snprintf(errstr, len, "unable to set socket buffer size");
276 perr = 1;
277 break;
278 case IESETTOS:
279 snprintf(errstr, len, "unable to set IP TOS");
280 perr = 1;
281 break;
282 case IESETCOS:
283 snprintf(errstr, len, "unable to set IPv6 traffic class");
284 perr = 1;
285 break;
286 case IESETFLOW:
287 snprintf(errstr, len, "unable to set IPv6 flow label");
288 break;
289 case IEREUSEADDR:
290 snprintf(errstr, len, "unable to reuse address on socket");
291 perr = 1;
292 break;
293 case IENONBLOCKING:
294 snprintf(errstr, len, "unable to set socket to non-blocking");
295 perr = 1;
296 break;
297 case IESETWINDOWSIZE:
298 snprintf(errstr, len, "unable to set socket window size");
299 perr = 1;
300 break;
301 case IEPROTOCOL:
302 snprintf(errstr, len, "protocol does not exist");
303 break;
304 case IEAFFINITY:
305 snprintf(errstr, len, "unable to set CPU affinity");
306 perr = 1;
307 break;
308 case IEDAEMON:
309 snprintf(errstr, len, "unable to become a daemon");
310 perr = 1;
311 break;
312 case IECREATESTREAM:
313 snprintf(errstr, len, "unable to create a new stream");
314 herr = 1;
315 perr = 1;
316 break;
317 case IEINITSTREAM:
318 snprintf(errstr, len, "unable to initialize stream");
319 herr = 1;
320 perr = 1;
321 break;
322 case IESTREAMLISTEN:
323 snprintf(errstr, len, "unable to start stream listener");
324 herr = 1;
325 perr = 1;
326 break;
327 case IESTREAMCONNECT:
328 snprintf(errstr, len, "unable to connect stream");
329 herr = 1;
330 perr = 1;
331 break;
332 case IESTREAMACCEPT:
333 snprintf(errstr, len, "unable to accept stream connection");
334 perr = 1;
335 break;
336 case IESTREAMWRITE:
337 snprintf(errstr, len, "unable to write to stream socket");
338 perr = 1;
339 break;
340 case IESTREAMREAD:
341 snprintf(errstr, len, "unable to read from stream socket");
342 perr = 1;
343 break;
344 case IESTREAMCLOSE:
345 snprintf(errstr, len, "stream socket has closed unexpectedly");
346 break;
347 case IESTREAMID:
348 snprintf(errstr, len, "stream has an invalid id");
349 break;
350 case IENEWTIMER:
351 snprintf(errstr, len, "unable to create new timer");
352 perr = 1;
353 break;
354 case IEUPDATETIMER:
355 snprintf(errstr, len, "unable to update timer");
356 perr = 1;
357 break;
358 case IESETCONGESTION:
359 snprintf(errstr, len, "unable to set TCP_CONGESTION: "
360 "Supplied congestion control algorithm not supported on this host");
361 break;
362 case IEPIDFILE:
363 snprintf(errstr, len, "unable to write PID file");
364 perr = 1;
365 break;
366 case IEV6ONLY:
367 snprintf(errstr, len, "Unable to set/reset IPV6_V6ONLY");
368 perr = 1;
369 break;
370 case IESETSCTPDISABLEFRAG:
371 snprintf(errstr, len, "unable to set SCTP_DISABLE_FRAGMENTS");
372 perr = 1;
373 break;
374 case IESETSCTPNSTREAM:
375 snprintf(errstr, len, "unable to set SCTP_INIT num of SCTP streams\n");
376 perr = 1;
377 break;
378 case IESETPACING:
379 snprintf(errstr, len, "unable to set socket pacing");
380 perr = 1;
381 break;
382 case IESETBUF2:
383 snprintf(errstr, len, "socket buffer size not set correctly");
384 break;
385 case IEREVERSEBIDIR:
386 snprintf(errstr, len, "cannot be both reverse and bidirectional");
387 break;
388
389 }
390
391 /* Append the result of strerror() or gai_strerror() if appropriate */
392 if (herr || perr)
393 strncat(errstr, ": ", len - strlen(errstr) - 1);
394 if (errno && perr)
395 strncat(errstr, strerror(errno), len - strlen(errstr) - 1);
396 else if (herr && gerror) {
397 strncat(errstr, gai_strerror(gerror), len - strlen(errstr) - 1);
398 gerror = 0;
399 }
400
401 return errstr;
402 }
403