1 #include "netperf_version.h" 2 3 char netsh_id[]="\ 4 @(#)netsh.c (c) Copyright 1993-2007 Hewlett-Packard Company. Version 2.4.3pre"; 5 6 7 /****************************************************************/ 8 /* */ 9 /* Global include files */ 10 /* */ 11 /****************************************************************/ 12 13 #ifdef HAVE_CONFIG_H 14 #include "config.h" 15 #endif 16 17 #include <sys/types.h> 18 #ifndef WIN32 19 #include <unistd.h> 20 #ifndef __VMS 21 #include <sys/ipc.h> 22 #endif /* __VMS */ 23 #endif /* WIN32 */ 24 #include <fcntl.h> 25 #ifndef WIN32 26 #include <errno.h> 27 #include <signal.h> 28 #endif /* !WIN32 */ 29 #include <stdio.h> 30 #include <stdlib.h> 31 #include <ctype.h> 32 /* the following four includes should not be needed ?*/ 33 #ifndef WIN32 34 #include <sys/time.h> 35 #include <sys/socket.h> 36 #include <netinet/in.h> 37 #include <netdb.h> 38 #else 39 #include <time.h> 40 #include <winsock2.h> 41 #define netperf_socklen_t socklen_t 42 #endif 43 44 #ifndef STRINGS 45 #include <string.h> 46 #else /* STRINGS */ 47 #include <strings.h> 48 #endif /* STRINGS */ 49 50 #ifdef WIN32 51 extern int getopt(int , char **, char *) ; 52 #else 53 double atof(const char *); 54 #endif /* WIN32 */ 55 56 /**********************************************************************/ 57 /* */ 58 /* Local Include Files */ 59 /* */ 60 /**********************************************************************/ 61 62 #define NETSH 63 #include "netsh.h" 64 #include "netlib.h" 65 #include "nettest_bsd.h" 66 67 #ifdef WANT_UNIX 68 #include "nettest_unix.h" 69 #ifndef WIN32 70 #include "sys/socket.h" 71 #endif /* !WIN32 */ 72 #endif /* WANT_UNIX */ 73 74 #ifdef WANT_XTI 75 #include "nettest_xti.h" 76 #endif /* WANT_XTI */ 77 78 #ifdef WANT_DLPI 79 #include "nettest_dlpi.h" 80 #endif /* WANT_DLPI */ 81 82 #ifdef WANT_SCTP 83 #include "nettest_sctp.h" 84 #endif 85 86 87 /************************************************************************/ 88 /* */ 89 /* Global constants and macros */ 90 /* */ 91 /************************************************************************/ 92 93 /* Some of the args take optional parameters. Since we are using */ 94 /* getopt to parse the command line, we will tell getopt that they do */ 95 /* not take parms, and then look for them ourselves */ 96 #define GLOBAL_CMD_LINE_ARGS "A:a:b:B:CcdDf:F:H:hi:I:k:K:l:L:n:NO:o:P:p:rt:T:v:VW:w:46" 97 98 /************************************************************************/ 99 /* */ 100 /* Extern variables */ 101 /* */ 102 /************************************************************************/ 103 104 /* 105 extern int errno; 106 extern char *sys_errlist[ ]; 107 extern int sys_nerr; 108 */ 109 110 /************************************************************************/ 111 /* */ 112 /* Global variables */ 113 /* */ 114 /************************************************************************/ 115 116 /* some names and such */ 117 char *program; /* program invocation name */ 118 char username[BUFSIZ]; /* login name of user */ 119 char cmd_file[BUFSIZ]; /* name of the commands file */ 120 121 /* stuff to say where this test is going */ 122 char host_name[HOSTNAMESIZE]; /* remote host name or ip addr */ 123 char local_host_name[HOSTNAMESIZE]; /* local hostname or ip */ 124 char test_name[BUFSIZ]; /* which test to run */ 125 char test_port[PORTBUFSIZE]; /* where is the test waiting */ 126 char local_test_port[PORTBUFSIZE]; /* from whence we should start */ 127 int address_family; /* which address family remote */ 128 int local_address_family; /* which address family local */ 129 130 /* the source of data for filling the buffers */ 131 char fill_file[BUFSIZ]; 132 133 /* output controlling variables */ 134 int 135 debug, /* debugging level */ 136 print_headers, /* do/don't display headers */ 137 verbosity; /* verbosity level */ 138 139 /* When specified with -B, this will be displayed at the end of the line 140 for output that does not include the test header. mostly this is 141 to help identify a specific netperf result when concurrent netperfs 142 are run. raj 2006-02-01 */ 143 char *result_brand = NULL; 144 145 /* cpu variables */ 146 int 147 local_cpu_usage, /* you guessed it */ 148 remote_cpu_usage; /* still right ! */ 149 150 float 151 local_cpu_rate, 152 remote_cpu_rate; 153 154 int 155 shell_num_cpus=1; 156 157 /* the end-test conditions for the tests - either transactions, bytes, */ 158 /* or time. different vars used for clarity - space is cheap ;-) */ 159 int 160 test_time, /* test ends by time */ 161 test_len_ticks, /* how many times will the timer go off before */ 162 /* the test is over? */ 163 test_bytes, /* test ends on byte count */ 164 test_trans; /* test ends on tran count */ 165 166 /* the alignment conditions for the tests */ 167 int 168 local_recv_align, /* alignment for local receives */ 169 local_send_align, /* alignment for local sends */ 170 local_send_offset = 0, 171 local_recv_offset = 0, 172 remote_recv_align, /* alignment for remote receives */ 173 remote_send_align, /* alignment for remote sends */ 174 remote_send_offset = 0, 175 remote_recv_offset = 0; 176 177 #if defined(WANT_INTERVALS) || defined(WANT_DEMO) 178 int 179 interval_usecs, 180 interval_wate, 181 interval_burst; 182 183 int demo_mode; /* are we actually in demo mode? */ 184 double demo_interval = 1000000.0; /* what is the desired interval to 185 display interval results. default 186 is one second in units of 187 microseconds */ 188 double demo_units = 0.0; /* what is our current best guess as 189 to how many work units must be 190 done to be near the desired 191 reporting interval? */ 192 193 double units_this_tick; 194 #endif 195 196 #ifdef DIRTY 197 int loc_dirty_count; 198 int loc_clean_count; 199 int rem_dirty_count; 200 int rem_clean_count; 201 #endif /* DIRTY */ 202 203 /* some of the vairables for confidence intervals... */ 204 205 int confidence_level; 206 int iteration_min; 207 int iteration_max; 208 int result_confidence_only = 0; 209 210 double interval; 211 212 /* stuff to control the "width" of the buffer rings for sending and */ 213 /* receiving data */ 214 int send_width; 215 int recv_width; 216 217 /* address family */ 218 int af = AF_INET; 219 220 /* did someone request processor affinity? */ 221 int cpu_binding_requested = 0; 222 223 /* are we not establishing a control connection? */ 224 int no_control = 0; 225 226 char netserver_usage[] = "\n\ 227 Usage: netserver [options] \n\ 228 \n\ 229 Options:\n\ 230 -h Display this text\n\ 231 -d Increase debugging output\n\ 232 -L name,family Use name to pick listen address and family for family\n\ 233 -p portnum Listen for connect requests on portnum.\n\ 234 -4 Do IPv4\n\ 235 -6 Do IPv6\n\ 236 -v verbosity Specify the verbosity level\n\ 237 -V Display version information and exit\n\ 238 \n"; 239 240 /* netperf_usage done as two concatenated strings to make the MS 241 compiler happy when compiling for x86_32. fix from Spencer 242 Frink. */ 243 244 char netperf_usage1[] = "\n\ 245 Usage: netperf [global options] -- [test options] \n\ 246 \n\ 247 Global options:\n\ 248 -a send,recv Set the local send,recv buffer alignment\n\ 249 -A send,recv Set the remote send,recv buffer alignment\n\ 250 -B brandstr Specify a string to be emitted with brief output\n\ 251 -c [cpu_rate] Report local CPU usage\n\ 252 -C [cpu_rate] Report remote CPU usage\n\ 253 -d Increase debugging output\n\ 254 -D [secs,units] * Display interim results at least every secs seconds\n\ 255 using units as the initial guess for units per second\n\ 256 -f G|M|K|g|m|k Set the output units\n\ 257 -F fill_file Pre-fill buffers with data from fill_file\n\ 258 -h Display this text\n\ 259 -H name|ip,fam * Specify the target machine and/or local ip and family\n\ 260 -i max,min Specify the max and min number of iterations (15,1)\n\ 261 -I lvl[,intvl] Specify confidence level (95 or 99) (99) \n\ 262 and confidence interval in percentage (10)\n\ 263 -l testlen Specify test duration (>0 secs) (<0 bytes|trans)\n\ 264 -L name|ip,fam * Specify the local ip|name and address family\n\ 265 -o send,recv Set the local send,recv buffer offsets\n\ 266 -O send,recv Set the remote send,recv buffer offset\n\ 267 -n numcpu Set the number of processors for CPU util\n\ 268 -N Establish no control connection, do 'send' side only\n\ 269 -p port,lport* Specify netserver port number and/or local port\n\ 270 -P 0|1 Don't/Do display test headers\n\ 271 -r Allow confidence to be hit on result only\n\ 272 -t testname Specify test to perform\n\ 273 -T lcpu,rcpu Request netperf/netserver be bound to local/remote cpu\n\ 274 -v verbosity Specify the verbosity level\n\ 275 -W send,recv Set the number of send,recv buffers\n\ 276 -v level Set the verbosity level (default 1, min 0)\n\ 277 -V Display the netperf version and exit\n"; 278 279 char netperf_usage2[] = "\n\ 280 For those options taking two parms, at least one must be specified;\n\ 281 specifying one value without a comma will set both parms to that\n\ 282 value, specifying a value with a leading comma will set just the second\n\ 283 parm, a value with a trailing comma will set just the first. To set\n\ 284 each parm to unique values, specify both and separate them with a\n\ 285 comma.\n\ 286 \n" 287 "* For these options taking two parms, specifying one value with no comma\n\ 288 will only set the first parms and will leave the second at the default\n\ 289 value. To set the second value it must be preceded with a comma or be a\n\ 290 comma-separated pair. This is to retain previous netperf behaviour.\n"; 291 292 293 /* This routine will return the two arguments to the calling routine. */ 295 /* If the second argument is not specified, and there is no comma, */ 296 /* then the value of the second argument will be the same as the */ 297 /* value of the first. If there is a comma, then the value of the */ 298 /* second argument will be the value of the second argument ;-) */ 299 void 300 break_args(char *s, char *arg1, char *arg2) 301 302 { 303 char *ns; 304 ns = strchr(s,','); 305 if (ns) { 306 /* there was a comma arg2 should be the second arg*/ 307 *ns++ = '\0'; 308 while ((*arg2++ = *ns++) != '\0'); 309 } 310 else { 311 /* there was not a comma, we can use ns as a temp s */ 312 /* and arg2 should be the same value as arg1 */ 313 ns = s; 314 while ((*arg2++ = *ns++) != '\0'); 315 }; 316 while ((*arg1++ = *s++) != '\0'); 317 } 318 319 /* break_args_explicit 320 321 this routine is somewhat like break_args in that it will separate a 322 pair of comma-separated values. however, if there is no comma, 323 this version will not ass-u-me that arg2 should be the same as 324 arg1. raj 2005-02-04 */ 325 void 326 break_args_explicit(char *s, char *arg1, char *arg2) 327 328 { 329 char *ns; 330 ns = strchr(s,','); 331 if (ns) { 332 /* there was a comma arg2 should be the second arg*/ 333 *ns++ = '\0'; 334 while ((*arg2++ = *ns++) != '\0'); 335 } 336 else { 337 /* there was not a comma, so we should make sure that arg2 is \0 338 lest something become confused. raj 2005-02-04 */ 339 *arg2 = '\0'; 340 }; 341 while ((*arg1++ = *s++) != '\0'); 342 343 } 344 345 /* given a string with possible values for setting an address family, 346 convert that into one of the AF_mumble values - AF_INET, AF_INET6, 347 AF_UNSPEC as apropriate. the family_string is compared in a 348 case-insensitive manner */ 349 350 int 351 parse_address_family(char family_string[]) 352 { 353 354 char temp[10]; /* gotta love magic constants :) */ 355 356 strncpy(temp,family_string,10); 357 358 if (debug) { 359 fprintf(where, 360 "Attempting to parse address family from %s derived from %s\n", 361 temp, 362 family_string); 363 } 364 #if defined(AF_INET6) 365 if (strstr(temp,"6")) { 366 return(AF_INET6); 367 } 368 #endif 369 if (strstr(temp,"inet") || 370 strstr(temp,"4")) { 371 return(AF_INET); 372 } 373 if (strstr(temp,"unspec") || 374 strstr(temp,"0")) { 375 return(AF_UNSPEC); 376 } 377 fprintf(where, 378 "WARNING! %s not recognized as an address family, using AF_UNPSEC\n", 379 family_string); 380 fprintf(where, 381 "Are you sure netperf was configured for that address family?\n"); 382 fflush(where); 383 return(AF_UNSPEC); 384 } 385 386 387 void 389 set_defaults() 390 { 391 392 /* stuff to say where this test is going */ 393 strcpy(host_name,""); /* remote host name or ip addr */ 394 strcpy(local_host_name,""); /* we want it to be INADDR_ANY */ 395 strcpy(test_name,"TCP_STREAM"); /* which test to run */ 396 strncpy(test_port,"12865",PORTBUFSIZE); /* where is the test waiting */ 397 strncpy(local_test_port,"0",PORTBUFSIZE);/* INPORT_ANY as it were */ 398 address_family = AF_UNSPEC; 399 local_address_family = AF_UNSPEC; 400 401 /* output controlling variables */ 402 debug = 0;/* debugging level */ 403 print_headers = 1;/* do print test headers */ 404 verbosity = 1;/* verbosity level */ 405 /* cpu variables */ 406 local_cpu_usage = 0;/* measure local cpu */ 407 remote_cpu_usage = 0;/* what do you think ;-) */ 408 409 local_cpu_rate = (float)0.0; 410 remote_cpu_rate = (float)0.0; 411 412 /* the end-test conditions for the tests - either transactions, bytes, */ 413 /* or time. different vars used for clarity - space is cheap ;-) */ 414 test_time = 10; /* test ends by time */ 415 test_bytes = 0; /* test ends on byte count */ 416 test_trans = 0; /* test ends on tran count */ 417 418 /* the alignment conditions for the tests */ 419 local_recv_align = 8; /* alignment for local receives */ 420 local_send_align = 8; /* alignment for local sends */ 421 remote_recv_align = 8; /* alignment for remote receives*/ 422 remote_send_align = 8; /* alignment for remote sends */ 423 424 #ifdef WANT_INTERVALS 425 /* rate controlling stuff */ 426 interval_usecs = 0; 427 interval_wate = 1; 428 interval_burst = 0; 429 #endif /* WANT_INTERVALS */ 430 431 #ifdef DIRTY 432 /* dirty and clean cache stuff */ 433 loc_dirty_count = 0; 434 loc_clean_count = 0; 435 rem_dirty_count = 0; 436 rem_clean_count = 0; 437 #endif /* DIRTY */ 438 439 /* some of the vairables for confidence intervals... */ 440 441 confidence_level = 99; 442 iteration_min = 1; 443 iteration_max = 1; 444 interval = 0.05; /* five percent? */ 445 446 no_control = 0; 447 strcpy(fill_file,""); 448 } 449 450 451 void 453 print_netserver_usage() 454 { 455 fwrite(netserver_usage, sizeof(char), strlen(netserver_usage), stderr); 456 } 457 458 459 void 461 print_netperf_usage() 462 { 463 fwrite(netperf_usage1, sizeof(char), strlen(netperf_usage1), stderr); 464 fwrite(netperf_usage2, sizeof(char), strlen(netperf_usage2), stderr); 465 } 466 467 void 468 scan_cmd_line(int argc, char *argv[]) 469 { 470 extern int optind; /* index of first unused arg */ 471 extern char *optarg; /* pointer to option string */ 472 473 int c; 474 475 char arg1[BUFSIZ], /* argument holders */ 476 arg2[BUFSIZ]; 477 478 program = (char *)malloc(strlen(argv[0]) + 1); 479 if (program == NULL) { 480 printf("malloc(%d) failed!\n", strlen(argv[0]) + 1); 481 exit(1); 482 } 483 strcpy(program, argv[0]); 484 485 /* Go through all the command line arguments and break them */ 486 /* out. For those options that take two parms, specifying only */ 487 /* the first will set both to that value. Specifying only the */ 488 /* second will leave the first untouched. To change only the */ 489 /* first, use the form first, (see the routine break_args.. */ 490 491 while ((c= getopt(argc, argv, GLOBAL_CMD_LINE_ARGS)) != EOF) { 492 switch (c) { 493 case '?': 494 case 'h': 495 print_netperf_usage(); 496 exit(1); 497 case 'a': 498 /* set local alignments */ 499 break_args(optarg,arg1,arg2); 500 if (arg1[0]) { 501 local_send_align = convert(arg1); 502 } 503 if (arg2[0]) 504 local_recv_align = convert(arg2); 505 break; 506 case 'A': 507 /* set remote alignments */ 508 break_args(optarg,arg1,arg2); 509 if (arg1[0]) { 510 remote_send_align = convert(arg1); 511 } 512 if (arg2[0]) 513 remote_recv_align = convert(arg2); 514 break; 515 case 'c': 516 /* measure local cpu usage please. the user */ 517 /* may have specified the cpu rate as an */ 518 /* optional parm */ 519 if (argv[optind] && isdigit((unsigned char)argv[optind][0])){ 520 /* there was an optional parm */ 521 local_cpu_rate = (float)atof(argv[optind]); 522 optind++; 523 } 524 local_cpu_usage++; 525 break; 526 case 'C': 527 /* measure remote cpu usage please */ 528 if (argv[optind] && isdigit((unsigned char)argv[optind][0])){ 529 /* there was an optional parm */ 530 remote_cpu_rate = (float)atof(argv[optind]); 531 optind++; 532 } 533 remote_cpu_usage++; 534 break; 535 case 'd': 536 debug++; 537 break; 538 case 'D': 539 #if (defined WANT_DEMO) 540 demo_mode++; 541 if (argv[optind] && isdigit((unsigned char)argv[optind][0])){ 542 /* there was an optional parm */ 543 break_args_explicit(argv[optind],arg1,arg2); 544 optind++; 545 if (arg1[0]) { 546 demo_interval = atof(arg1) * 1000000.0; 547 } 548 if (arg2[0]) { 549 demo_units = convert(arg2); 550 } 551 } 552 #else 553 printf("Sorry, Demo Mode not configured into this netperf.\n"); 554 printf("please consider reconfiguring netperf with\n"); 555 printf("--enable-demo=yes and recompiling\n"); 556 #endif 557 break; 558 case 'f': 559 /* set the thruput formatting */ 560 libfmt = *optarg; 561 break; 562 case 'F': 563 /* set the fill_file variable for pre-filling buffers */ 564 strcpy(fill_file,optarg); 565 break; 566 case 'i': 567 /* set the iterations min and max for confidence intervals */ 568 break_args(optarg,arg1,arg2); 569 if (arg1[0]) { 570 iteration_max = convert(arg1); 571 } 572 if (arg2[0] ) { 573 iteration_min = convert(arg2); 574 } 575 /* if the iteration_max is < iteration_min make iteration_max 576 equal iteration_min */ 577 if (iteration_max < iteration_min) iteration_max = iteration_min; 578 /* limit minimum to 3 iterations */ 579 if (iteration_max < 3) iteration_max = 3; 580 if (iteration_min < 3) iteration_min = 3; 581 /* limit maximum to 30 iterations */ 582 if (iteration_max > 30) iteration_max = 30; 583 if (iteration_min > 30) iteration_min = 30; 584 break; 585 case 'I': 586 /* set the confidence level (95 or 99) and width */ 587 break_args(optarg,arg1,arg2); 588 if (arg1[0]) { 589 confidence_level = convert(arg1); 590 } 591 if((confidence_level != 95) && (confidence_level != 99)){ 592 printf("Only 95%% and 99%% confidence level is supported\n"); 593 exit(1); 594 } 595 if (arg2[0] ) { 596 interval = (double) convert(arg2)/100; 597 } 598 /* make sure that iteration_min and iteration_max are at least 599 at a reasonable default value. if a -i option has previously 600 been parsed, these will no longer be 1, so we can check 601 against 1 */ 602 if (iteration_min == 1) iteration_min = 3; 603 if (iteration_max == 1) iteration_max = 10; 604 605 break; 606 case 'k': 607 /* local dirty and clean counts */ 608 #ifdef DIRTY 609 break_args(optarg,arg1,arg2); 610 if (arg1[0]) { 611 loc_dirty_count = convert(arg1); 612 } 613 if (arg2[0] ) { 614 loc_clean_count = convert(arg2); 615 } 616 #else 617 printf("I don't know how to get dirty.\n"); 618 #endif /* DIRTY */ 619 break; 620 case 'K': 621 /* remote dirty and clean counts */ 622 #ifdef DIRTY 623 break_args(optarg,arg1,arg2); 624 if (arg1[0]) { 625 rem_dirty_count = convert(arg1); 626 } 627 if (arg2[0] ) { 628 rem_clean_count = convert(arg2); 629 } 630 #else 631 printf("I don't know how to get dirty.\n"); 632 #endif /* DIRTY */ 633 break; 634 case 'n': 635 shell_num_cpus = atoi(optarg); 636 break; 637 case 'N': 638 no_control = 1; 639 break; 640 case 'o': 641 /* set the local offsets */ 642 break_args(optarg,arg1,arg2); 643 if (arg1[0]) 644 local_send_offset = convert(arg1); 645 if (arg2[0]) 646 local_recv_offset = convert(arg2); 647 break; 648 case 'O': 649 /* set the remote offsets */ 650 break_args(optarg,arg1,arg2); 651 if (arg1[0]) 652 remote_send_offset = convert(arg1); 653 if (arg2[0]) 654 remote_recv_offset = convert(arg2); 655 break; 656 case 'P': 657 /* to print or not to print, that is */ 658 /* the header question */ 659 print_headers = convert(optarg); 660 break; 661 case 'r': 662 /* the user wishes that we declare confidence when hit on the 663 result even if not yet reached on CPU utilization. only 664 meaningful if cpu util is enabled */ 665 result_confidence_only = 1; 666 break; 667 case 't': 668 /* set the test name */ 669 strcpy(test_name,optarg); 670 break; 671 case 'T': 672 /* We want to set the processor on which netserver or netperf */ 673 /* will run */ 674 break_args(optarg,arg1,arg2); 675 if (arg1[0]) { 676 local_proc_affinity = convert(arg1); 677 bind_to_specific_processor(local_proc_affinity,0); 678 } 679 if (arg2[0]) { 680 remote_proc_affinity = convert(arg2); 681 } 682 cpu_binding_requested = 1; 683 break; 684 case 'W': 685 /* set the "width" of the user space data buffer ring. This will */ 686 /* be the number of send_size buffers malloc'd in the tests */ 687 break_args(optarg,arg1,arg2); 688 if (arg1[0]) 689 send_width = convert(arg1); 690 if (arg2[0]) 691 recv_width = convert(arg2); 692 break; 693 case 'l': 694 /* determine test end conditions */ 695 /* assume a timed test */ 696 test_time = convert(optarg); 697 test_bytes = test_trans = 0; 698 if (test_time < 0) { 699 test_bytes = -1 * test_time; 700 test_trans = test_bytes; 701 test_time = 0; 702 } 703 break; 704 case 'v': 705 /* say how much to say */ 706 verbosity = convert(optarg); 707 break; 708 case 'p': 709 /* specify an alternate port number we use break_args_explicit 710 here to maintain backwards compatibility with previous 711 generations of netperf where having a single value did not 712 set both remote _and_ local port number. raj 2005-02-04 */ 713 break_args_explicit(optarg,arg1,arg2); 714 if (arg1[0]) 715 strncpy(test_port,arg1,PORTBUFSIZE); 716 if (arg2[0]) 717 strncpy(local_test_port,arg2,PORTBUFSIZE); 718 break; 719 case 'H': 720 /* save-off the host identifying information, use 721 break_args_explicit since passing just one value should not 722 set both */ 723 break_args_explicit(optarg,arg1,arg2); 724 if (arg1[0]) 725 strncpy(host_name,arg1,sizeof(host_name)); 726 if (arg2[0]) 727 address_family = parse_address_family(arg2); 728 break; 729 case 'L': 730 /* save-off the local control socket addressing information. use 731 break_args_explicit since passing just one value should not 732 set both */ 733 break_args_explicit(optarg,arg1,arg2); 734 if (arg1[0]) 735 strncpy(local_host_name,arg1,sizeof(local_host_name)); 736 if (arg2[0]) 737 local_address_family = parse_address_family(arg2); 738 break; 739 case 'w': 740 /* We want to send requests at a certain wate. */ 741 /* Remember that there are 1000000 usecs in a */ 742 /* second, and that the packet rate is */ 743 /* expressed in packets per millisecond. */ 744 #ifdef WANT_INTERVALS 745 interval_usecs = convert_timespec(optarg); 746 interval_wate = interval_usecs / 1000; 747 #else 748 fprintf(where, 749 "Packet rate control is not compiled in.\n"); 750 #endif 751 break; 752 case 'b': 753 /* we want to have a burst so many packets per */ 754 /* interval. */ 755 #ifdef WANT_INTERVALS 756 interval_burst = convert(optarg); 757 #else 758 fprintf(where, 759 "Packet burst size is not compiled in. \n"); 760 #endif /* WANT_INTERVALS */ 761 break; 762 case 'B': 763 result_brand = malloc(strlen(optarg)+1); 764 if (NULL != result_brand) { 765 strcpy(result_brand,optarg); 766 } 767 else { 768 fprintf(where, 769 "Unable to malloc space for result brand\n"); 770 } 771 break; 772 case '4': 773 address_family = AF_INET; 774 local_address_family = AF_INET; 775 break; 776 case '6': 777 #if defined(AF_INET6) 778 address_family = AF_INET6; 779 local_address_family = AF_INET6; 780 #else 781 printf("This netperf was not compiled on an IPv6 capable system!\n"); 782 exit(-1); 783 #endif 784 break; 785 case 'V': 786 printf("Netperf version %s\n",NETPERF_VERSION); 787 exit(0); 788 break; 789 }; 790 } 791 /* ok, what should our default hostname and local binding info be? 792 */ 793 if ('\0' == host_name[0]) { 794 /* host_name was not set */ 795 switch (address_family) { 796 case AF_INET: 797 strcpy(host_name,"localhost"); 798 break; 799 case AF_UNSPEC: 800 /* what to do here? case it off the local_address_family I 801 suppose */ 802 switch (local_address_family) { 803 case AF_INET: 804 case AF_UNSPEC: 805 strcpy(host_name,"localhost"); 806 break; 807 #if defined(AF_INET6) 808 case AF_INET6: 809 strcpy(host_name,"::1"); 810 break; 811 #endif 812 default: 813 printf("Netperf does not understand %d as an address family\n", 814 address_family); 815 exit(-1); 816 } 817 break; 818 #if defined(AF_INET6) 819 case AF_INET6: 820 strcpy(host_name,"::1"); 821 break; 822 #endif 823 default: 824 printf("Netperf does not understand %d as an address family\n", 825 address_family); 826 exit(-1); 827 } 828 } 829 830 /* now, having established the name to which the control will 831 connect, from what should it come? */ 832 if ('\0' == local_host_name[0]) { 833 switch (local_address_family) { 834 case AF_INET: 835 strcpy(local_host_name,"0.0.0.0"); 836 break; 837 case AF_UNSPEC: 838 switch (address_family) { 839 case AF_INET: 840 case AF_UNSPEC: 841 strcpy(local_host_name,"0.0.0.0"); 842 break; 843 #if defined(AF_INET6) 844 case AF_INET6: 845 strcpy(local_host_name,"::0"); 846 break; 847 #endif 848 default: 849 printf("Netperf does not understand %d as an address family\n", 850 address_family); 851 exit(-1); 852 } 853 break; 854 #if defined(AF_INET6) 855 case AF_INET6: 856 strcpy(local_host_name,"::0"); 857 break; 858 #endif 859 default: 860 printf("Netperf does not understand %d as an address family\n", 861 address_family); 862 exit(-1); 863 } 864 } 865 866 /* so, if we aren't even going to establish a control connection we 867 should set certain "remote" settings to reflect this, regardless 868 of what else may have been set on the command line */ 869 if (no_control) { 870 remote_recv_align = -1; 871 remote_send_align = -1; 872 remote_send_offset = -1; 873 remote_recv_offset = -1; 874 remote_cpu_rate = (float)-1.0; 875 remote_cpu_usage = 0; 876 } 877 878 /* parsing test-specific options used to be conditional on there 879 being a "--" in the option stream. however, some of the tests 880 have other initialization happening in their "scan" routines so we 881 want to call them regardless. raj 2005-02-08 */ 882 if ((strcasecmp(test_name,"TCP_STREAM") == 0) || 883 #ifdef HAVE_ICSC_EXS 884 (strcasecmp(test_name,"EXS_TCP_STREAM") == 0) || 885 #endif /* HAVE_ICSC_EXS */ 886 #ifdef HAVE_SENDFILE 887 (strcasecmp(test_name,"TCP_SENDFILE") == 0) || 888 #endif /* HAVE_SENDFILE */ 889 (strcasecmp(test_name,"TCP_MAERTS") == 0) || 890 (strcasecmp(test_name,"TCP_RR") == 0) || 891 (strcasecmp(test_name,"TCP_CRR") == 0) || 892 (strcasecmp(test_name,"TCP_CC") == 0) || 893 #ifdef DO_1644 894 (strcasecmp(test_name,"TCP_TRR") == 0) || 895 #endif /* DO_1644 */ 896 #ifdef DO_NBRR 897 (strcasecmp(test_name,"TCP_TRR") == 0) || 898 #endif /* DO_NBRR */ 899 (strcasecmp(test_name,"UDP_STREAM") == 0) || 900 (strcasecmp(test_name,"UDP_RR") == 0)) 901 { 902 scan_sockets_args(argc, argv); 903 } 904 905 #ifdef WANT_DLPI 906 else if ((strcasecmp(test_name,"DLCO_RR") == 0) || 907 (strcasecmp(test_name,"DLCL_RR") == 0) || 908 (strcasecmp(test_name,"DLCO_STREAM") == 0) || 909 (strcasecmp(test_name,"DLCL_STREAM") == 0)) 910 { 911 scan_dlpi_args(argc, argv); 912 } 913 #endif /* WANT_DLPI */ 914 915 #ifdef WANT_UNIX 916 else if ((strcasecmp(test_name,"STREAM_RR") == 0) || 917 (strcasecmp(test_name,"DG_RR") == 0) || 918 (strcasecmp(test_name,"STREAM_STREAM") == 0) || 919 (strcasecmp(test_name,"DG_STREAM") == 0)) 920 { 921 scan_unix_args(argc, argv); 922 } 923 #endif /* WANT_UNIX */ 924 925 #ifdef WANT_XTI 926 else if ((strcasecmp(test_name,"XTI_TCP_RR") == 0) || 927 (strcasecmp(test_name,"XTI_TCP_STREAM") == 0) || 928 (strcasecmp(test_name,"XTI_UDP_RR") == 0) || 929 (strcasecmp(test_name,"XTI_UDP_STREAM") == 0)) 930 { 931 scan_xti_args(argc, argv); 932 } 933 #endif /* WANT_XTI */ 934 935 #ifdef WANT_SCTP 936 else if ((strcasecmp(test_name,"SCTP_STREAM") == 0) || 937 (strcasecmp(test_name,"SCTP_RR") == 0) || 938 (strcasecmp(test_name,"SCTP_STREAM_MANY") == 0) || 939 (strcasecmp(test_name,"SCTP_RR_MANY") == 0)) 940 { 941 scan_sctp_args(argc, argv); 942 } 943 #endif 944 945 #ifdef WANT_SDP 946 else if((strcasecmp(test_name,"SDP_STREAM") == 0) || 947 (strcasecmp(test_name,"SDP_MAERTS") == 0) || 948 (strcasecmp(test_name,"SDP_RR") == 0)) 949 { 950 scan_sdp_args(argc, argv); 951 } 952 #endif 953 954 /* what is our default value for the output units? if the test 955 name contains "RR" or "rr" or "Rr" or "rR" then the default is 956 'x' for transactions. otherwise it is 'm' for megabits 957 (10^6) */ 958 959 if ('?' == libfmt) { 960 /* we use a series of strstr's here because not everyone has 961 strcasestr and I don't feel like up or downshifting text */ 962 if ((strstr(test_name,"RR")) || 963 (strstr(test_name,"rr")) || 964 (strstr(test_name,"Rr")) || 965 (strstr(test_name,"rR"))) { 966 libfmt = 'x'; 967 } 968 else { 969 libfmt = 'm'; 970 } 971 } 972 else if ('x' == libfmt) { 973 /* now, a format of 'x' makes no sense for anything other than 974 an RR test. if someone has been silly enough to try to set 975 that, we will reset it silently to default - namely 'm' */ 976 if ((strstr(test_name,"RR") == NULL) && 977 (strstr(test_name,"rr") == NULL) && 978 (strstr(test_name,"Rr") == NULL) && 979 (strstr(test_name,"rR") == NULL)) { 980 libfmt = 'm'; 981 } 982 } 983 } 984 985 986 void 988 dump_globals() 989 { 990 printf("Program name: %s\n", program); 991 printf("Local send alignment: %d\n",local_send_align); 992 printf("Local recv alignment: %d\n",local_recv_align); 993 printf("Remote send alignment: %d\n",remote_send_align); 994 printf("Remote recv alignment: %d\n",remote_recv_align); 995 printf("Report local CPU %d\n",local_cpu_usage); 996 printf("Report remote CPU %d\n",remote_cpu_usage); 997 printf("Verbosity: %d\n",verbosity); 998 printf("Debug: %d\n",debug); 999 printf("Port: %s\n",test_port); 1000 printf("Test name: %s\n",test_name); 1001 printf("Test bytes: %d Test time: %d Test trans: %d\n", 1002 test_bytes, 1003 test_time, 1004 test_trans); 1005 printf("Host name: %s\n",host_name); 1006 printf("\n"); 1007 } 1008