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
232enum 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
243union 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
252union 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
261struct 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
315extern 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
363struct 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
408int getopt(int argc, char **argv, char *optstring);
409
410extern char *optarg;		/* returned arg to go with this option */
411extern int optind;		/* index to next argv element to process */
412extern int opterr;		/* should error messages be printed? */
413extern int optopt;		/* */
414
415#endif /* _GETOPT_ */
416
417extern  SOCKET     win_kludge_socket, win_kludge_socket2;
418#endif /* WIN32 */
419
420extern  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 */
424extern char local_data_port[10];
425extern char remote_data_port[10];
426
427extern char *local_data_address;
428extern char *remote_data_address;
429
430extern int local_data_family;
431extern int remote_data_family;
432
433extern  union netperf_request_struct netperf_request;
434extern  union netperf_response_struct netperf_response;
435
436extern  float    lib_local_cpu_util;
437extern  float    lib_elapsed;
438extern  float    lib_local_maxrate;
439
440extern  char    libfmt;
441
442extern  int     cpu_method;
443extern  int     lib_num_loc_cpus;
444extern  int     lib_num_rem_cpus;
445extern  SOCKET  server_sock;
446extern  int     times_up;
447extern  FILE    *where;
448extern  int     loops_per_msec;
449extern  float   lib_local_per_cpu_util[];
450
451extern  void    netlib_init();
452extern  int     netlib_get_page_size();
453extern  void    install_signal_catchers();
454extern  void    establish_control(char hostname[],
455				  char port[],
456				  int af,
457				  char local_hostname[],
458				  char local_port[],
459				  int local_af);
460extern  void    shutdown_control();
461extern  void    init_stat();
462extern  void    send_request();
463extern  void    recv_response();
464extern  void    send_response();
465extern  void    recv_request();
466extern  void    dump_request();
467extern  void    dump_addrinfo(FILE *dumploc, struct addrinfo *info,
468			      char *host, char *port, int family);
469extern  void    start_timer(int time);
470extern  void    stop_timer();
471extern  void    cpu_start(int measure_cpu);
472extern  void    cpu_stop(int measure_cpu, float *elapsed);
473extern  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);
480extern  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);
486extern  void    display_confidence();
487extern  void    set_sock_buffer(SOCKET sd,
488				enum sock_buffer which,
489				int requested_size,
490				int *effective_sizep);
491extern  char   *format_units();
492
493extern  char    *inet_ftos(int family);
494extern  char    *inet_ttos(int type);
495extern  char    *inet_ptos(int protocol);
496extern  double  ntohd(double net_double);
497extern  double  htond(double host_double);
498extern  int     inet_nton(int af, const void *src, char *dst, int cnt);
499extern  void    libmain();
500extern  double  calc_thruput(double units_received);
501extern  double  calc_thruput_interval(double units_received,double elapsed);
502extern  double  calc_thruput_omni(double units_received);
503extern  double  calc_thruput_interval_omni(double units_received,double elapsed);
504extern  float   calibrate_local_cpu(float local_cpu_rate);
505extern  float   calibrate_remote_cpu();
506extern  void    bind_to_specific_processor(int processor_affinity,int use_cpu_map);
507extern 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
515extern int msec_sleep( int msecs );
516#endif  /* WIN32 */
517extern  float   calc_cpu_util(float elapsed_time);
518extern  float	calc_service_demand(double units_sent,
519				    float elapsed_time,
520				    float cpu_utilization,
521				    int num_cpus);
522extern  float	calc_service_demand_trans(double units_sent,
523					  float elapsed_time,
524					  float cpu_utilization,
525					  int num_cpus);
526#if defined(__hpux)
527extern  void    catcher(int, siginfo_t *,void *);
528#else
529extern  void    catcher(int);
530#endif /* __hpux */
531extern  struct ring_elt *allocate_buffer_ring();
532extern void access_buffer(char *buffer_ptr,
533			  int length,
534			  int dirty_count,
535			  int clean_count);
536
537#ifdef HAVE_ICSC_EXS
538extern  struct ring_elt *allocate_exs_buffer_ring();
539#endif /* HAVE_ICSC_EXS */
540#ifdef HAVE_SENDFILE
541extern  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 */
548extern int dl_connect(int fd, unsigned char *remote_addr, int remote_addr_len);
549extern int dl_bind(int fd, int sap, int mode, char *dlsap_ptr, int *dlsap_len);
550extern  int     dl_open(char devfile[], int ppa);
551#endif /* WANT_DLPI */
552extern  char    format_cpu_method(int method);
553extern unsigned int convert(char *string);
554extern unsigned int convert_timespec(char *string);
555
556#ifdef WANT_INTERVALS
557extern void start_itimer(unsigned int interval_len_msec);
558#endif
559 /* these are all for the confidence interval stuff */
560extern 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