1 /* 2 Copyright (C) 1993-2005 Hewlett-Packard Company 3 */ 4 5 #ifdef HAVE_CONFIG_H 6 #include "config.h" 7 #endif 8 9 #if defined(HAVE_SYS_SOCKET_H) 10 # include <sys/socket.h> 11 #endif 12 #if defined(HAVE_NETDB_H) 13 # include <netdb.h> 14 #endif 15 #if !defined(HAVE_GETADDRINFO) || !defined(HAVE_GETNAMEINFO) 16 # include "missing/getaddrinfo.h" 17 #endif 18 19 #define PAD_TIME 4 20 /* library routine specifc defines */ 21 #define MAXSPECDATA 62 /* how many ints worth of data */ 22 /* can tests send... */ 23 #define MAXTIMES 4 /* how many times may we loop */ 24 /* to calibrate */ 25 #define MAXCPUS 256 /* how many CPU's can we track */ 26 #define MAXMESSAGESIZE 65536 27 #define MAXALIGNMENT 16384 28 #define MAXOFFSET 4096 29 #define DATABUFFERLEN MAXMESSAGESIZE+MAXALIGNMENT+MAXOFFSET 30 31 #define DEBUG_ON 1 32 #define DEBUG_OFF 2 33 #define DEBUG_OK 3 34 #define NODE_IDENTIFY 4 35 #define CPU_CALIBRATE 5 36 37 #define DO_TCP_STREAM 10 38 #define TCP_STREAM_RESPONSE 11 39 #define TCP_STREAM_RESULTS 12 40 41 #define DO_TCP_RR 13 42 #define TCP_RR_RESPONSE 14 43 #define TCP_RR_RESULTS 15 44 45 #define DO_UDP_STREAM 16 46 #define UDP_STREAM_RESPONSE 17 47 #define UDP_STREAM_RESULTS 18 48 49 #define DO_UDP_RR 19 50 #define UDP_RR_RESPONSE 20 51 #define UDP_RR_RESULTS 21 52 53 #define DO_DLPI_CO_STREAM 22 54 #define DLPI_CO_STREAM_RESPONSE 23 55 #define DLPI_CO_STREAM_RESULTS 24 56 57 #define DO_DLPI_CO_RR 25 58 #define DLPI_CO_RR_RESPONSE 26 59 #define DLPI_CO_RR_RESULTS 27 60 61 #define DO_DLPI_CL_STREAM 28 62 #define DLPI_CL_STREAM_RESPONSE 29 63 #define DLPI_CL_STREAM_RESULTS 30 64 65 #define DO_DLPI_CL_RR 31 66 #define DLPI_CL_RR_RESPONSE 32 67 #define DLPI_CL_RR_RESULTS 33 68 69 #define DO_TCP_CRR 34 70 #define TCP_CRR_RESPONSE 35 71 #define TCP_CRR_RESULTS 36 72 73 #define DO_STREAM_STREAM 37 74 #define STREAM_STREAM_RESPONSE 38 75 #define STREAM_STREAM_RESULTS 39 76 77 #define DO_STREAM_RR 40 78 #define STREAM_RR_RESPONSE 41 79 #define STREAM_RR_RESULTS 42 80 81 #define DO_DG_STREAM 43 82 #define DG_STREAM_RESPONSE 44 83 #define DG_STREAM_RESULTS 45 84 85 #define DO_DG_RR 46 86 #define DG_RR_RESPONSE 47 87 #define DG_RR_RESULTS 48 88 89 #define DO_FORE_STREAM 49 90 #define FORE_STREAM_RESPONSE 50 91 #define FORE_STREAM_RESULTS 51 92 93 #define DO_FORE_RR 52 94 #define FORE_RR_RESPONSE 53 95 #define FORE_RR_RESULTS 54 96 97 #define DO_HIPPI_STREAM 55 98 #define HIPPI_STREAM_RESPONSE 56 99 #define HIPPI_STREAM_RESULTS 57 100 101 #define DO_HIPPI_RR 52 102 #define HIPPI_RR_RESPONSE 53 103 #define HIPPI_RR_RESULTS 54 104 105 #define DO_XTI_TCP_STREAM 55 106 #define XTI_TCP_STREAM_RESPONSE 56 107 #define XTI_TCP_STREAM_RESULTS 57 108 109 #define DO_XTI_TCP_RR 58 110 #define XTI_TCP_RR_RESPONSE 59 111 #define XTI_TCP_RR_RESULTS 60 112 113 #define DO_XTI_UDP_STREAM 61 114 #define XTI_UDP_STREAM_RESPONSE 62 115 #define XTI_UDP_STREAM_RESULTS 63 116 117 #define DO_XTI_UDP_RR 64 118 #define XTI_UDP_RR_RESPONSE 65 119 #define XTI_UDP_RR_RESULTS 66 120 121 #define DO_XTI_TCP_CRR 67 122 #define XTI_TCP_CRR_RESPONSE 68 123 #define XTI_TCP_CRR_RESULTS 69 124 125 #define DO_TCP_TRR 70 126 #define TCP_TRR_RESPONSE 71 127 #define TCP_TRR_RESULTS 72 128 129 #define DO_TCP_NBRR 73 130 #define TCP_NBRR_RESPONSE 74 131 #define TCP_NBRR_RESULTS 75 132 133 #define DO_TCPIPV6_STREAM 76 134 #define TCPIPV6_STREAM_RESPONSE 77 135 #define TCPIPV6_STREAM_RESULTS 78 136 137 #define DO_TCPIPV6_RR 79 138 #define TCPIPV6_RR_RESPONSE 80 139 #define TCPIPV6_RR_RESULTS 81 140 141 #define DO_UDPIPV6_STREAM 82 142 #define UDPIPV6_STREAM_RESPONSE 83 143 #define UDPIPV6_STREAM_RESULTS 84 144 145 #define DO_UDPIPV6_RR 85 146 #define UDPIPV6_RR_RESPONSE 86 147 #define UDPIPV6_RR_RESULTS 87 148 149 #define DO_TCPIPV6_CRR 88 150 #define TCPIPV6_CRR_RESPONSE 89 151 #define TCPIPV6_CRR_RESULTS 90 152 153 #define DO_TCPIPV6_TRR 91 154 #define TCPIPV6_TRR_RESPONSE 92 155 #define TCPIPV6_TRR_RESULTS 93 156 157 #define DO_TCP_MAERTS 94 158 #define TCP_MAERTS_RESPONSE 95 159 #define TCP_MAERTS_RESULTS 96 160 161 #define DO_LWPSTR_STREAM 100 162 #define LWPSTR_STREAM_RESPONSE 110 163 #define LWPSTR_STREAM_RESULTS 120 164 165 #define DO_LWPSTR_RR 130 166 #define LWPSTR_RR_RESPONSE 140 167 #define LWPSTR_RR_RESULTS 150 168 169 #define DO_LWPDG_STREAM 160 170 #define LWPDG_STREAM_RESPONSE 170 171 #define LWPDG_STREAM_RESULTS 180 172 173 #define DO_LWPDG_RR 190 174 #define LWPDG_RR_RESPONSE 200 175 #define LWPDG_RR_RESULTS 210 176 177 #define DO_TCP_CC 300 178 #define TCP_CC_RESPONSE 301 179 #define TCP_CC_RESULTS 302 180 181 /* The DNS_RR test has been removed from netperf but we leave these 182 here for historical purposes. Those wanting to do DNS_RR tests 183 should use netperf4 instead. */ 184 #define DO_DNS_RR 400 185 #define DNS_RR_RESPONSE 401 186 #define DNS_RR_RESULTS 402 187 188 #define DO_SCTP_STREAM 500 189 #define SCTP_STREAM_RESPONSE 501 190 #define SCTP_STREAM_RESULT 502 191 192 #define DO_SCTP_STREAM_MANY 510 193 #define SCTP_STREAM_MANY_RESPONSE 511 194 #define SCTP_STREAM_MANY_RESULT 512 195 196 #define DO_SCTP_RR 520 197 #define SCTP_RR_RESPONSE 521 198 #define SCTP_RR_RESULT 502 199 200 #define DO_SCTP_RR_MANY 530 201 #define SCTP_RR_MANY_RESPONSE 531 202 #define SCTP_RR_MANY_RESULT 532 203 204 #define DO_SDP_STREAM 540 205 #define SDP_STREAM_RESPONSE 541 206 #define SDP_STREAM_RESULTS 542 207 208 #define DO_SDP_RR 543 209 #define SDP_RR_RESPONSE 544 210 #define SDP_RR_RESULTS 545 211 212 #define DO_SDP_MAERTS 546 213 #define SDP_MAERTS_RESPONSE 547 214 #define SDP_MAERTS_RESULTS 548 215 216 #define DO_SDP_CRR 549 217 #define SDP_CRR_RESPONSE 550 218 #define SDP_CRR_RESULTS 551 219 220 #define DO_SDP_CC 552 221 #define SDP_CC_RESPONSE 553 222 #define SDP_CC_RESULTS 554 223 224 #if HAVE_INTTYPES_H 225 # include <inttypes.h> 226 #else 227 # if HAVE_STDINT_H 228 # include <stdint.h> 229 # endif 230 #endif 231 232 enum sock_buffer{ 233 SEND_BUFFER, 234 RECV_BUFFER 235 }; 236 237 /* some of the fields in these structures are going to be doubles and */ 238 /* such. so, we probably want to ensure that they will start on */ 239 /* "double" boundaries. this will break compatability to pre-2.1 */ 240 /* releases, but then, backwards compatability has never been a */ 241 /* stated goal of netperf. raj 11/95 */ 242 243 union netperf_request_struct { 244 struct { 245 int request_type; 246 int dummy; 247 int test_specific_data[MAXSPECDATA]; 248 } content; 249 double dummy; 250 }; 251 252 union netperf_response_struct { 253 struct { 254 int response_type; 255 int serv_errno; 256 int test_specific_data[MAXSPECDATA]; 257 } content; 258 double dummy; 259 }; 260 261 struct ring_elt { 262 struct ring_elt *next; /* next element in the ring */ 263 char *buffer_base; /* in case we have to free it at somepoint */ 264 char *buffer_ptr; /* the aligned and offset pointer */ 265 }; 266 267 /* +*+ SAF Sorry about the hacks with errno; NT made me do it :( 268 269 WinNT does define an errno. 270 It is mostly a legacy from the XENIX days. 271 272 Depending upon the version of the C run time that is linked in, it is 273 either a simple variable (like UNIX code expects), but more likely it 274 is the address of a procedure to return the error number. So any 275 code that sets errno is likely to be overwriting the address of this 276 procedure. Worse, only a tiny fraction of NT's errors get set 277 through errno. 278 279 So I have changed the netperf code to use a define Set_errno when 280 that is it's intent. On non-windows platforms this is just an 281 assignment to errno. But on NT this calls SetLastError. 282 283 I also define errno (now only used on right side of assignments) 284 on NT to be GetLastError. 285 286 Similarly, perror is defined on NT, but it only accesses the same 287 XENIX errors that errno covers. So on NT this is redefined to be 288 Perror and it expands all GetLastError texts. */ 289 290 291 #ifdef WIN32 292 /* INVALID_SOCKET == INVALID_HANDLE_VALUE == (unsigned int)(~0) */ 293 /* SOCKET_ERROR == -1 */ 294 #define ENOTSOCK WSAENOTSOCK 295 #define EINTR WSAEINTR 296 #define ENOBUFS WSAENOBUFS 297 #define EWOULDBLOCK WSAEWOULDBLOCK 298 #define EAFNOSUPPORT WSAEAFNOSUPPORT 299 /* I don't use a C++ style of comment because it upsets some C 300 compilers, possibly even when it is inside an ifdef WIN32... */ 301 /* from public\sdk\inc\crt\errno.h */ 302 #define ENOSPC 28 303 304 #ifdef errno 305 /* delete the one from stdlib.h */ 306 /*#define errno (*_errno()) */ 307 #undef errno 308 #endif 309 #define errno GetLastError() 310 #define Set_errno(num) SetLastError((num)) 311 312 #define perror(text) PrintWin32Error(stderr, (text)) 313 #define Print_errno(stream, text) PrintWin32Error((stream), (text)) 314 315 extern void PrintWin32Error(FILE *stream, LPSTR text); 316 317 #if !defined(NT_PERF) && !defined(USE_LOOPER) 318 #define NT_PERF 319 #endif 320 #else 321 /* Really shouldn't use manifest constants! */ 322 /*+*+SAF There are other examples of "== -1" and "<0" that probably */ 323 /*+*+SAF should be cleaned up as well. */ 324 #define INVALID_SOCKET -1 325 #define SOCKET_ERROR -1 326 327 #define SOCKET int 328 #define Set_errno(num) errno = (num) 329 330 #define Print_errno(stream, text) fprintf((stream), "%s errno %d\n", (text), errno) 331 #endif 332 333 /* Robin & Rick's kludge to try to have a timer signal EINTR by closing */ 334 /* the socket from another thread can also return several other errors. */ 335 /* Let's define a macro to hide all of this. */ 336 337 #ifndef WIN32 338 #define SOCKET_EINTR(return_value) (errno == EINTR) 339 #define SOCKET_EADDRINUSE(return_value) (errno == EADDRINUSE) 340 #define SOCKET_EADDRNOTAVAIL(return_value) (errno == EADDRNOTAVAIL) 341 342 #else 343 344 /* not quite sure I like the extra cases for WIN32 but that is what my 345 WIN32 expert sugested. I'm not sure what WSA's to put for 346 EADDRINUSE */ 347 348 #define SOCKET_EINTR(return_value) \ 349 (((return_value) == SOCKET_ERROR) && \ 350 ((errno == EINTR) || \ 351 (errno == WSAECONNABORTED) || \ 352 (errno == WSAECONNRESET) )) 353 #define SOCKET_EADDRINUSE(return_value) \ 354 (((return_value) == SOCKET_ERROR) && \ 355 ((errno == WSAEADDRINUSE) )) 356 #define SOCKET_EADDRNOTAVAIL(return_value) \ 357 (((return_value) == SOCKET_ERROR) && \ 358 ((errno == WSAEADDRNOTAVAIL) )) 359 #endif 360 361 #ifdef HAVE_SENDFILE 362 363 struct sendfile_ring_elt { 364 struct sendfile_ring_elt *next; /* next element in the ring */ 365 int fildes; /* the file descriptor of the source 366 file */ 367 off_t offset; /* the offset from the beginning of 368 the file for this send */ 369 size_t length; /* the number of bytes to send - 370 this is redundant with the 371 send_size variable but I decided 372 to include it anyway */ 373 struct iovec *hdtrl; /* a pointer to a header/trailer 374 that we do not initially use and 375 so should be set to NULL when the 376 ring is setup. */ 377 int flags; /* the flags to pass to sendfile() - 378 presently unused and should be 379 set to zero when the ring is 380 setup. */ 381 }; 382 383 #endif /* HAVE_SENDFILE */ 384 385 /* the diferent codes to denote the type of CPU utilization */ 386 /* methods used */ 387 #define CPU_UNKNOWN 0 388 #define HP_IDLE_COUNTER 1 389 #define PSTAT 2 390 #define TIMES 3 391 #define LOOPER 4 392 #define GETRUSAGE 5 393 #define NT_METHOD 6 394 #define KSTAT 7 395 #define PROC_STAT 8 396 #define SYSCTL 9 397 #define PERFSTAT 10 398 #define KSTAT_10 11 399 #define OSX 12 400 401 #define BADCH ('?') 402 403 #ifndef NETLIB 404 #ifdef WIN32 405 #ifndef _GETOPT_ 406 #define _GETOPT_ 407 408 int getopt(int argc, char **argv, char *optstring); 409 410 extern char *optarg; /* returned arg to go with this option */ 411 extern int optind; /* index to next argv element to process */ 412 extern int opterr; /* should error messages be printed? */ 413 extern int optopt; /* */ 414 415 #endif /* _GETOPT_ */ 416 417 extern SOCKET win_kludge_socket, win_kludge_socket2; 418 #endif /* WIN32 */ 419 420 extern int local_proc_affinity, remote_proc_affinity; 421 422 /* these are to allow netperf to be run easily through those evil, 423 end-to-end breaking things known as firewalls */ 424 extern char local_data_port[10]; 425 extern char remote_data_port[10]; 426 427 extern char *local_data_address; 428 extern char *remote_data_address; 429 430 extern int local_data_family; 431 extern int remote_data_family; 432 433 extern union netperf_request_struct netperf_request; 434 extern union netperf_response_struct netperf_response; 435 436 extern float lib_local_cpu_util; 437 extern float lib_elapsed; 438 extern float lib_local_maxrate; 439 440 extern char libfmt; 441 442 extern int cpu_method; 443 extern int lib_num_loc_cpus; 444 extern int lib_num_rem_cpus; 445 extern SOCKET server_sock; 446 extern int times_up; 447 extern FILE *where; 448 extern int loops_per_msec; 449 extern float lib_local_per_cpu_util[]; 450 451 extern void netlib_init(); 452 extern int netlib_get_page_size(); 453 extern void install_signal_catchers(); 454 extern void establish_control(char hostname[], 455 char port[], 456 int af, 457 char local_hostname[], 458 char local_port[], 459 int local_af); 460 extern void shutdown_control(); 461 extern void init_stat(); 462 extern void send_request(); 463 extern void recv_response(); 464 extern void send_response(); 465 extern void recv_request(); 466 extern void dump_request(); 467 extern void dump_addrinfo(FILE *dumploc, struct addrinfo *info, 468 char *host, char *port, int family); 469 extern void start_timer(int time); 470 extern void stop_timer(); 471 extern void cpu_start(int measure_cpu); 472 extern void cpu_stop(int measure_cpu, float *elapsed); 473 extern void calculate_confidence(int confidence_iterations, 474 float time, 475 double result, 476 float loc_cpu, 477 float rem_cpu, 478 float loc_sd, 479 float rem_sd); 480 extern void retrieve_confident_values(float *elapsed_time, 481 double *thruput, 482 float *local_cpu_utilization, 483 float *remote_cpu_utilization, 484 float *local_service_demand, 485 float *remote_service_demand); 486 extern void display_confidence(); 487 extern void set_sock_buffer(SOCKET sd, 488 enum sock_buffer which, 489 int requested_size, 490 int *effective_sizep); 491 extern char *format_units(); 492 493 extern char *inet_ftos(int family); 494 extern char *inet_ttos(int type); 495 extern char *inet_ptos(int protocol); 496 extern double ntohd(double net_double); 497 extern double htond(double host_double); 498 extern int inet_nton(int af, const void *src, char *dst, int cnt); 499 extern void libmain(); 500 extern double calc_thruput(double units_received); 501 extern double calc_thruput_interval(double units_received,double elapsed); 502 extern double calc_thruput_omni(double units_received); 503 extern double calc_thruput_interval_omni(double units_received,double elapsed); 504 extern float calibrate_local_cpu(float local_cpu_rate); 505 extern float calibrate_remote_cpu(); 506 extern void bind_to_specific_processor(int processor_affinity,int use_cpu_map); 507 extern int set_nonblock (SOCKET sock); 508 509 #ifndef WIN32 510 511 /* WIN32 requires that at least one of the file sets to select be 512 non-null. Since msec_sleep routine is only called by nettest_dlpi & 513 nettest_unix, let's duck this issue. */ 514 515 extern int msec_sleep( int msecs ); 516 #endif /* WIN32 */ 517 extern float calc_cpu_util(float elapsed_time); 518 extern float calc_service_demand(double units_sent, 519 float elapsed_time, 520 float cpu_utilization, 521 int num_cpus); 522 extern float calc_service_demand_trans(double units_sent, 523 float elapsed_time, 524 float cpu_utilization, 525 int num_cpus); 526 #if defined(__hpux) 527 extern void catcher(int, siginfo_t *,void *); 528 #else 529 extern void catcher(int); 530 #endif /* __hpux */ 531 extern struct ring_elt *allocate_buffer_ring(); 532 extern void access_buffer(char *buffer_ptr, 533 int length, 534 int dirty_count, 535 int clean_count); 536 537 #ifdef HAVE_ICSC_EXS 538 extern struct ring_elt *allocate_exs_buffer_ring(); 539 #endif /* HAVE_ICSC_EXS */ 540 #ifdef HAVE_SENDFILE 541 extern struct sendfile_ring_elt *alloc_sendfile_buf_ring(); 542 #endif /* HAVE_SENDFILE */ 543 #ifdef WANT_DLPI 544 /* it seems that AIX in its finite wisdom has some bogus define in an 545 include file which defines "rem_addr" which then screws-up this extern 546 unless we change the names to protect the guilty. reported by Eric 547 Jones */ 548 extern int dl_connect(int fd, unsigned char *remote_addr, int remote_addr_len); 549 extern int dl_bind(int fd, int sap, int mode, char *dlsap_ptr, int *dlsap_len); 550 extern int dl_open(char devfile[], int ppa); 551 #endif /* WANT_DLPI */ 552 extern char format_cpu_method(int method); 553 extern unsigned int convert(char *string); 554 extern unsigned int convert_timespec(char *string); 555 556 #ifdef WANT_INTERVALS 557 extern void start_itimer(unsigned int interval_len_msec); 558 #endif 559 /* these are all for the confidence interval stuff */ 560 extern double confidence; 561 562 #endif 563 564 #ifdef WIN32 565 #define close(x) closesocket(x) 566 #define strcasecmp(a,b) _stricmp(a,b) 567 #define getpid() ((int)GetCurrentProcessId()) 568 #endif 569 570 #ifdef WIN32 571 #if 0 572 /* Should really use safe string functions; but not for now... */ 573 #include <strsafe.h> 574 /* Microsoft has deprecated _snprintf; it isn't guarenteed to null terminate the result buffer. */ 575 /* They want us to call StringCbPrintf instead; it always null terminates the string. */ 576 #endif 577 578 #define snprintf _snprintf 579 #endif 580 581 /* Define a macro to align a buffer with an offset from a power of 2 582 boundary. */ 583 584 #ifndef WIN32 585 #define ULONG_PTR unsigned long 586 #endif 587 588 #define ALIGN_BUFFER(BufPtr, Align, Offset) \ 589 (char *)(( (ULONG_PTR)(BufPtr) + \ 590 (ULONG_PTR) (Align) -1) & \ 591 ~((ULONG_PTR) (Align) - 1)) + (ULONG_PTR)(Offset) 592 593 /* if your system has bcopy and bzero, include it here, otherwise, we */ 594 /* will try to use memcpy aand memset. fix from Bruce Barnett @ GE. */ 595 #if defined(hpux) || defined (__VMS) 596 #define HAVE_BCOPY 597 #define HAVE_BZERO 598 #endif 599 600 #ifdef WIN32 601 #define HAVE_MIN 602 #else 603 #define _stdcall 604 #define _cdecl 605 #endif 606 607 #ifndef HAVE_BCOPY 608 #define bcopy(s,d,h) memcpy((d),(s),(h)) 609 #endif /* HAVE_BCOPY */ 610 611 #ifndef HAVE_BZERO 612 #define bzero(p,h) memset((p),0,(h)) 613 #endif /* HAVE_BZERO */ 614 615 #ifndef HAVE_MIN 616 #define min(a,b) ((a < b) ? a : b) 617 #endif /* HAVE_MIN */ 618 619 #ifdef USE_PERFSTAT 620 # include <libperfstat.h> 621 #endif 622