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 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 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 * 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