| /* |
| Copyright (C) 1993-2005 Hewlett-Packard Company |
| */ |
| |
| #ifdef HAVE_CONFIG_H |
| #include "config.h" |
| #endif |
| |
| #if defined(HAVE_SYS_SOCKET_H) |
| # include <sys/socket.h> |
| #endif |
| #if defined(HAVE_NETDB_H) |
| # include <netdb.h> |
| #endif |
| #if !defined(HAVE_GETADDRINFO) || !defined(HAVE_GETNAMEINFO) |
| # include "missing/getaddrinfo.h" |
| #endif |
| |
| #define PAD_TIME 4 |
| /* library routine specifc defines */ |
| #define MAXSPECDATA 62 /* how many ints worth of data */ |
| /* can tests send... */ |
| #define MAXTIMES 4 /* how many times may we loop */ |
| /* to calibrate */ |
| #define MAXCPUS 256 /* how many CPU's can we track */ |
| #define MAXMESSAGESIZE 65536 |
| #define MAXALIGNMENT 16384 |
| #define MAXOFFSET 4096 |
| #define DATABUFFERLEN MAXMESSAGESIZE+MAXALIGNMENT+MAXOFFSET |
| |
| #define DEBUG_ON 1 |
| #define DEBUG_OFF 2 |
| #define DEBUG_OK 3 |
| #define NODE_IDENTIFY 4 |
| #define CPU_CALIBRATE 5 |
| |
| #define DO_TCP_STREAM 10 |
| #define TCP_STREAM_RESPONSE 11 |
| #define TCP_STREAM_RESULTS 12 |
| |
| #define DO_TCP_RR 13 |
| #define TCP_RR_RESPONSE 14 |
| #define TCP_RR_RESULTS 15 |
| |
| #define DO_UDP_STREAM 16 |
| #define UDP_STREAM_RESPONSE 17 |
| #define UDP_STREAM_RESULTS 18 |
| |
| #define DO_UDP_RR 19 |
| #define UDP_RR_RESPONSE 20 |
| #define UDP_RR_RESULTS 21 |
| |
| #define DO_DLPI_CO_STREAM 22 |
| #define DLPI_CO_STREAM_RESPONSE 23 |
| #define DLPI_CO_STREAM_RESULTS 24 |
| |
| #define DO_DLPI_CO_RR 25 |
| #define DLPI_CO_RR_RESPONSE 26 |
| #define DLPI_CO_RR_RESULTS 27 |
| |
| #define DO_DLPI_CL_STREAM 28 |
| #define DLPI_CL_STREAM_RESPONSE 29 |
| #define DLPI_CL_STREAM_RESULTS 30 |
| |
| #define DO_DLPI_CL_RR 31 |
| #define DLPI_CL_RR_RESPONSE 32 |
| #define DLPI_CL_RR_RESULTS 33 |
| |
| #define DO_TCP_CRR 34 |
| #define TCP_CRR_RESPONSE 35 |
| #define TCP_CRR_RESULTS 36 |
| |
| #define DO_STREAM_STREAM 37 |
| #define STREAM_STREAM_RESPONSE 38 |
| #define STREAM_STREAM_RESULTS 39 |
| |
| #define DO_STREAM_RR 40 |
| #define STREAM_RR_RESPONSE 41 |
| #define STREAM_RR_RESULTS 42 |
| |
| #define DO_DG_STREAM 43 |
| #define DG_STREAM_RESPONSE 44 |
| #define DG_STREAM_RESULTS 45 |
| |
| #define DO_DG_RR 46 |
| #define DG_RR_RESPONSE 47 |
| #define DG_RR_RESULTS 48 |
| |
| #define DO_FORE_STREAM 49 |
| #define FORE_STREAM_RESPONSE 50 |
| #define FORE_STREAM_RESULTS 51 |
| |
| #define DO_FORE_RR 52 |
| #define FORE_RR_RESPONSE 53 |
| #define FORE_RR_RESULTS 54 |
| |
| #define DO_HIPPI_STREAM 55 |
| #define HIPPI_STREAM_RESPONSE 56 |
| #define HIPPI_STREAM_RESULTS 57 |
| |
| #define DO_HIPPI_RR 52 |
| #define HIPPI_RR_RESPONSE 53 |
| #define HIPPI_RR_RESULTS 54 |
| |
| #define DO_XTI_TCP_STREAM 55 |
| #define XTI_TCP_STREAM_RESPONSE 56 |
| #define XTI_TCP_STREAM_RESULTS 57 |
| |
| #define DO_XTI_TCP_RR 58 |
| #define XTI_TCP_RR_RESPONSE 59 |
| #define XTI_TCP_RR_RESULTS 60 |
| |
| #define DO_XTI_UDP_STREAM 61 |
| #define XTI_UDP_STREAM_RESPONSE 62 |
| #define XTI_UDP_STREAM_RESULTS 63 |
| |
| #define DO_XTI_UDP_RR 64 |
| #define XTI_UDP_RR_RESPONSE 65 |
| #define XTI_UDP_RR_RESULTS 66 |
| |
| #define DO_XTI_TCP_CRR 67 |
| #define XTI_TCP_CRR_RESPONSE 68 |
| #define XTI_TCP_CRR_RESULTS 69 |
| |
| #define DO_TCP_TRR 70 |
| #define TCP_TRR_RESPONSE 71 |
| #define TCP_TRR_RESULTS 72 |
| |
| #define DO_TCP_NBRR 73 |
| #define TCP_NBRR_RESPONSE 74 |
| #define TCP_NBRR_RESULTS 75 |
| |
| #define DO_TCPIPV6_STREAM 76 |
| #define TCPIPV6_STREAM_RESPONSE 77 |
| #define TCPIPV6_STREAM_RESULTS 78 |
| |
| #define DO_TCPIPV6_RR 79 |
| #define TCPIPV6_RR_RESPONSE 80 |
| #define TCPIPV6_RR_RESULTS 81 |
| |
| #define DO_UDPIPV6_STREAM 82 |
| #define UDPIPV6_STREAM_RESPONSE 83 |
| #define UDPIPV6_STREAM_RESULTS 84 |
| |
| #define DO_UDPIPV6_RR 85 |
| #define UDPIPV6_RR_RESPONSE 86 |
| #define UDPIPV6_RR_RESULTS 87 |
| |
| #define DO_TCPIPV6_CRR 88 |
| #define TCPIPV6_CRR_RESPONSE 89 |
| #define TCPIPV6_CRR_RESULTS 90 |
| |
| #define DO_TCPIPV6_TRR 91 |
| #define TCPIPV6_TRR_RESPONSE 92 |
| #define TCPIPV6_TRR_RESULTS 93 |
| |
| #define DO_TCP_MAERTS 94 |
| #define TCP_MAERTS_RESPONSE 95 |
| #define TCP_MAERTS_RESULTS 96 |
| |
| #define DO_LWPSTR_STREAM 100 |
| #define LWPSTR_STREAM_RESPONSE 110 |
| #define LWPSTR_STREAM_RESULTS 120 |
| |
| #define DO_LWPSTR_RR 130 |
| #define LWPSTR_RR_RESPONSE 140 |
| #define LWPSTR_RR_RESULTS 150 |
| |
| #define DO_LWPDG_STREAM 160 |
| #define LWPDG_STREAM_RESPONSE 170 |
| #define LWPDG_STREAM_RESULTS 180 |
| |
| #define DO_LWPDG_RR 190 |
| #define LWPDG_RR_RESPONSE 200 |
| #define LWPDG_RR_RESULTS 210 |
| |
| #define DO_TCP_CC 300 |
| #define TCP_CC_RESPONSE 301 |
| #define TCP_CC_RESULTS 302 |
| |
| /* The DNS_RR test has been removed from netperf but we leave these |
| here for historical purposes. Those wanting to do DNS_RR tests |
| should use netperf4 instead. */ |
| #define DO_DNS_RR 400 |
| #define DNS_RR_RESPONSE 401 |
| #define DNS_RR_RESULTS 402 |
| |
| #define DO_SCTP_STREAM 500 |
| #define SCTP_STREAM_RESPONSE 501 |
| #define SCTP_STREAM_RESULT 502 |
| |
| #define DO_SCTP_STREAM_MANY 510 |
| #define SCTP_STREAM_MANY_RESPONSE 511 |
| #define SCTP_STREAM_MANY_RESULT 512 |
| |
| #define DO_SCTP_RR 520 |
| #define SCTP_RR_RESPONSE 521 |
| #define SCTP_RR_RESULT 502 |
| |
| #define DO_SCTP_RR_MANY 530 |
| #define SCTP_RR_MANY_RESPONSE 531 |
| #define SCTP_RR_MANY_RESULT 532 |
| |
| #define DO_SDP_STREAM 540 |
| #define SDP_STREAM_RESPONSE 541 |
| #define SDP_STREAM_RESULTS 542 |
| |
| #define DO_SDP_RR 543 |
| #define SDP_RR_RESPONSE 544 |
| #define SDP_RR_RESULTS 545 |
| |
| #define DO_SDP_MAERTS 546 |
| #define SDP_MAERTS_RESPONSE 547 |
| #define SDP_MAERTS_RESULTS 548 |
| |
| #define DO_SDP_CRR 549 |
| #define SDP_CRR_RESPONSE 550 |
| #define SDP_CRR_RESULTS 551 |
| |
| #define DO_SDP_CC 552 |
| #define SDP_CC_RESPONSE 553 |
| #define SDP_CC_RESULTS 554 |
| |
| #if HAVE_INTTYPES_H |
| # include <inttypes.h> |
| #else |
| # if HAVE_STDINT_H |
| # include <stdint.h> |
| # endif |
| #endif |
| |
| enum sock_buffer{ |
| SEND_BUFFER, |
| RECV_BUFFER |
| }; |
| |
| /* some of the fields in these structures are going to be doubles and */ |
| /* such. so, we probably want to ensure that they will start on */ |
| /* "double" boundaries. this will break compatability to pre-2.1 */ |
| /* releases, but then, backwards compatability has never been a */ |
| /* stated goal of netperf. raj 11/95 */ |
| |
| union netperf_request_struct { |
| struct { |
| int request_type; |
| int dummy; |
| int test_specific_data[MAXSPECDATA]; |
| } content; |
| double dummy; |
| }; |
| |
| union netperf_response_struct { |
| struct { |
| int response_type; |
| int serv_errno; |
| int test_specific_data[MAXSPECDATA]; |
| } content; |
| double dummy; |
| }; |
| |
| struct ring_elt { |
| struct ring_elt *next; /* next element in the ring */ |
| char *buffer_base; /* in case we have to free it at somepoint */ |
| char *buffer_ptr; /* the aligned and offset pointer */ |
| }; |
| |
| /* +*+ SAF Sorry about the hacks with errno; NT made me do it :( |
| |
| WinNT does define an errno. |
| It is mostly a legacy from the XENIX days. |
| |
| Depending upon the version of the C run time that is linked in, it is |
| either a simple variable (like UNIX code expects), but more likely it |
| is the address of a procedure to return the error number. So any |
| code that sets errno is likely to be overwriting the address of this |
| procedure. Worse, only a tiny fraction of NT's errors get set |
| through errno. |
| |
| So I have changed the netperf code to use a define Set_errno when |
| that is it's intent. On non-windows platforms this is just an |
| assignment to errno. But on NT this calls SetLastError. |
| |
| I also define errno (now only used on right side of assignments) |
| on NT to be GetLastError. |
| |
| Similarly, perror is defined on NT, but it only accesses the same |
| XENIX errors that errno covers. So on NT this is redefined to be |
| Perror and it expands all GetLastError texts. */ |
| |
| |
| #ifdef WIN32 |
| /* INVALID_SOCKET == INVALID_HANDLE_VALUE == (unsigned int)(~0) */ |
| /* SOCKET_ERROR == -1 */ |
| #define ENOTSOCK WSAENOTSOCK |
| #define EINTR WSAEINTR |
| #define ENOBUFS WSAENOBUFS |
| #define EWOULDBLOCK WSAEWOULDBLOCK |
| #define EAFNOSUPPORT WSAEAFNOSUPPORT |
| /* I don't use a C++ style of comment because it upsets some C |
| compilers, possibly even when it is inside an ifdef WIN32... */ |
| /* from public\sdk\inc\crt\errno.h */ |
| #define ENOSPC 28 |
| |
| #ifdef errno |
| /* delete the one from stdlib.h */ |
| /*#define errno (*_errno()) */ |
| #undef errno |
| #endif |
| #define errno GetLastError() |
| #define Set_errno(num) SetLastError((num)) |
| |
| #define perror(text) PrintWin32Error(stderr, (text)) |
| #define Print_errno(stream, text) PrintWin32Error((stream), (text)) |
| |
| extern void PrintWin32Error(FILE *stream, LPSTR text); |
| |
| #if !defined(NT_PERF) && !defined(USE_LOOPER) |
| #define NT_PERF |
| #endif |
| #else |
| /* Really shouldn't use manifest constants! */ |
| /*+*+SAF There are other examples of "== -1" and "<0" that probably */ |
| /*+*+SAF should be cleaned up as well. */ |
| #define INVALID_SOCKET -1 |
| #define SOCKET_ERROR -1 |
| |
| #define SOCKET int |
| #define Set_errno(num) errno = (num) |
| |
| #define Print_errno(stream, text) fprintf((stream), "%s errno %d\n", (text), errno) |
| #endif |
| |
| /* Robin & Rick's kludge to try to have a timer signal EINTR by closing */ |
| /* the socket from another thread can also return several other errors. */ |
| /* Let's define a macro to hide all of this. */ |
| |
| #ifndef WIN32 |
| #define SOCKET_EINTR(return_value) (errno == EINTR) |
| #define SOCKET_EADDRINUSE(return_value) (errno == EADDRINUSE) |
| #define SOCKET_EADDRNOTAVAIL(return_value) (errno == EADDRNOTAVAIL) |
| |
| #else |
| |
| /* not quite sure I like the extra cases for WIN32 but that is what my |
| WIN32 expert sugested. I'm not sure what WSA's to put for |
| EADDRINUSE */ |
| |
| #define SOCKET_EINTR(return_value) \ |
| (((return_value) == SOCKET_ERROR) && \ |
| ((errno == EINTR) || \ |
| (errno == WSAECONNABORTED) || \ |
| (errno == WSAECONNRESET) )) |
| #define SOCKET_EADDRINUSE(return_value) \ |
| (((return_value) == SOCKET_ERROR) && \ |
| ((errno == WSAEADDRINUSE) )) |
| #define SOCKET_EADDRNOTAVAIL(return_value) \ |
| (((return_value) == SOCKET_ERROR) && \ |
| ((errno == WSAEADDRNOTAVAIL) )) |
| #endif |
| |
| #ifdef HAVE_SENDFILE |
| |
| struct sendfile_ring_elt { |
| struct sendfile_ring_elt *next; /* next element in the ring */ |
| int fildes; /* the file descriptor of the source |
| file */ |
| off_t offset; /* the offset from the beginning of |
| the file for this send */ |
| size_t length; /* the number of bytes to send - |
| this is redundant with the |
| send_size variable but I decided |
| to include it anyway */ |
| struct iovec *hdtrl; /* a pointer to a header/trailer |
| that we do not initially use and |
| so should be set to NULL when the |
| ring is setup. */ |
| int flags; /* the flags to pass to sendfile() - |
| presently unused and should be |
| set to zero when the ring is |
| setup. */ |
| }; |
| |
| #endif /* HAVE_SENDFILE */ |
| |
| /* the diferent codes to denote the type of CPU utilization */ |
| /* methods used */ |
| #define CPU_UNKNOWN 0 |
| #define HP_IDLE_COUNTER 1 |
| #define PSTAT 2 |
| #define TIMES 3 |
| #define LOOPER 4 |
| #define GETRUSAGE 5 |
| #define NT_METHOD 6 |
| #define KSTAT 7 |
| #define PROC_STAT 8 |
| #define SYSCTL 9 |
| #define PERFSTAT 10 |
| #define KSTAT_10 11 |
| #define OSX 12 |
| |
| #define BADCH ('?') |
| |
| #ifndef NETLIB |
| #ifdef WIN32 |
| #ifndef _GETOPT_ |
| #define _GETOPT_ |
| |
| int getopt(int argc, char **argv, char *optstring); |
| |
| extern char *optarg; /* returned arg to go with this option */ |
| extern int optind; /* index to next argv element to process */ |
| extern int opterr; /* should error messages be printed? */ |
| extern int optopt; /* */ |
| |
| #endif /* _GETOPT_ */ |
| |
| extern SOCKET win_kludge_socket, win_kludge_socket2; |
| #endif /* WIN32 */ |
| |
| extern int local_proc_affinity, remote_proc_affinity; |
| |
| /* these are to allow netperf to be run easily through those evil, |
| end-to-end breaking things known as firewalls */ |
| extern char local_data_port[10]; |
| extern char remote_data_port[10]; |
| |
| extern char *local_data_address; |
| extern char *remote_data_address; |
| |
| extern int local_data_family; |
| extern int remote_data_family; |
| |
| extern union netperf_request_struct netperf_request; |
| extern union netperf_response_struct netperf_response; |
| |
| extern float lib_local_cpu_util; |
| extern float lib_elapsed; |
| extern float lib_local_maxrate; |
| |
| extern char libfmt; |
| |
| extern int cpu_method; |
| extern int lib_num_loc_cpus; |
| extern int lib_num_rem_cpus; |
| extern SOCKET server_sock; |
| extern int times_up; |
| extern FILE *where; |
| extern int loops_per_msec; |
| extern float lib_local_per_cpu_util[]; |
| |
| extern void netlib_init(); |
| extern int netlib_get_page_size(); |
| extern void install_signal_catchers(); |
| extern void establish_control(char hostname[], |
| char port[], |
| int af, |
| char local_hostname[], |
| char local_port[], |
| int local_af); |
| extern void shutdown_control(); |
| extern void init_stat(); |
| extern void send_request(); |
| extern void recv_response(); |
| extern void send_response(); |
| extern void recv_request(); |
| extern void dump_request(); |
| extern void dump_addrinfo(FILE *dumploc, struct addrinfo *info, |
| char *host, char *port, int family); |
| extern void start_timer(int time); |
| extern void stop_timer(); |
| extern void cpu_start(int measure_cpu); |
| extern void cpu_stop(int measure_cpu, float *elapsed); |
| extern void calculate_confidence(int confidence_iterations, |
| float time, |
| double result, |
| float loc_cpu, |
| float rem_cpu, |
| float loc_sd, |
| float rem_sd); |
| extern void retrieve_confident_values(float *elapsed_time, |
| double *thruput, |
| float *local_cpu_utilization, |
| float *remote_cpu_utilization, |
| float *local_service_demand, |
| float *remote_service_demand); |
| extern void display_confidence(); |
| extern void set_sock_buffer(SOCKET sd, |
| enum sock_buffer which, |
| int requested_size, |
| int *effective_sizep); |
| extern char *format_units(); |
| |
| extern char *inet_ftos(int family); |
| extern char *inet_ttos(int type); |
| extern char *inet_ptos(int protocol); |
| extern double ntohd(double net_double); |
| extern double htond(double host_double); |
| extern int inet_nton(int af, const void *src, char *dst, int cnt); |
| extern void libmain(); |
| extern double calc_thruput(double units_received); |
| extern double calc_thruput_interval(double units_received,double elapsed); |
| extern double calc_thruput_omni(double units_received); |
| extern double calc_thruput_interval_omni(double units_received,double elapsed); |
| extern float calibrate_local_cpu(float local_cpu_rate); |
| extern float calibrate_remote_cpu(); |
| extern void bind_to_specific_processor(int processor_affinity,int use_cpu_map); |
| extern int set_nonblock (SOCKET sock); |
| |
| #ifndef WIN32 |
| |
| /* WIN32 requires that at least one of the file sets to select be |
| non-null. Since msec_sleep routine is only called by nettest_dlpi & |
| nettest_unix, let's duck this issue. */ |
| |
| extern int msec_sleep( int msecs ); |
| #endif /* WIN32 */ |
| extern float calc_cpu_util(float elapsed_time); |
| extern float calc_service_demand(double units_sent, |
| float elapsed_time, |
| float cpu_utilization, |
| int num_cpus); |
| extern float calc_service_demand_trans(double units_sent, |
| float elapsed_time, |
| float cpu_utilization, |
| int num_cpus); |
| #if defined(__hpux) |
| extern void catcher(int, siginfo_t *,void *); |
| #else |
| extern void catcher(int); |
| #endif /* __hpux */ |
| extern struct ring_elt *allocate_buffer_ring(); |
| extern void access_buffer(char *buffer_ptr, |
| int length, |
| int dirty_count, |
| int clean_count); |
| |
| #ifdef HAVE_ICSC_EXS |
| extern struct ring_elt *allocate_exs_buffer_ring(); |
| #endif /* HAVE_ICSC_EXS */ |
| #ifdef HAVE_SENDFILE |
| extern struct sendfile_ring_elt *alloc_sendfile_buf_ring(); |
| #endif /* HAVE_SENDFILE */ |
| #ifdef WANT_DLPI |
| /* it seems that AIX in its finite wisdom has some bogus define in an |
| include file which defines "rem_addr" which then screws-up this extern |
| unless we change the names to protect the guilty. reported by Eric |
| Jones */ |
| extern int dl_connect(int fd, unsigned char *remote_addr, int remote_addr_len); |
| extern int dl_bind(int fd, int sap, int mode, char *dlsap_ptr, int *dlsap_len); |
| extern int dl_open(char devfile[], int ppa); |
| #endif /* WANT_DLPI */ |
| extern char format_cpu_method(int method); |
| extern unsigned int convert(char *string); |
| extern unsigned int convert_timespec(char *string); |
| |
| #ifdef WANT_INTERVALS |
| extern void start_itimer(unsigned int interval_len_msec); |
| #endif |
| /* these are all for the confidence interval stuff */ |
| extern double confidence; |
| |
| #endif |
| |
| #ifdef WIN32 |
| #define close(x) closesocket(x) |
| #define strcasecmp(a,b) _stricmp(a,b) |
| #define getpid() ((int)GetCurrentProcessId()) |
| #endif |
| |
| #ifdef WIN32 |
| #if 0 |
| /* Should really use safe string functions; but not for now... */ |
| #include <strsafe.h> |
| /* Microsoft has deprecated _snprintf; it isn't guarenteed to null terminate the result buffer. */ |
| /* They want us to call StringCbPrintf instead; it always null terminates the string. */ |
| #endif |
| |
| #define snprintf _snprintf |
| #endif |
| |
| /* Define a macro to align a buffer with an offset from a power of 2 |
| boundary. */ |
| |
| #ifndef WIN32 |
| #define ULONG_PTR unsigned long |
| #endif |
| |
| #define ALIGN_BUFFER(BufPtr, Align, Offset) \ |
| (char *)(( (ULONG_PTR)(BufPtr) + \ |
| (ULONG_PTR) (Align) -1) & \ |
| ~((ULONG_PTR) (Align) - 1)) + (ULONG_PTR)(Offset) |
| |
| /* if your system has bcopy and bzero, include it here, otherwise, we */ |
| /* will try to use memcpy aand memset. fix from Bruce Barnett @ GE. */ |
| #if defined(hpux) || defined (__VMS) |
| #define HAVE_BCOPY |
| #define HAVE_BZERO |
| #endif |
| |
| #ifdef WIN32 |
| #define HAVE_MIN |
| #else |
| #define _stdcall |
| #define _cdecl |
| #endif |
| |
| #ifndef HAVE_BCOPY |
| #define bcopy(s,d,h) memcpy((d),(s),(h)) |
| #endif /* HAVE_BCOPY */ |
| |
| #ifndef HAVE_BZERO |
| #define bzero(p,h) memset((p),0,(h)) |
| #endif /* HAVE_BZERO */ |
| |
| #ifndef HAVE_MIN |
| #define min(a,b) ((a < b) ? a : b) |
| #endif /* HAVE_MIN */ |
| |
| #ifdef USE_PERFSTAT |
| # include <libperfstat.h> |
| #endif |