1#ifdef HAVE_CONFIG_H
2#include <config.h>
3#endif
4
5#ifdef WANT_OMNI
6char nettest_omni_id[]="\
7@(#)nettest_omni.c (c) Copyright 2008-2012 Hewlett-Packard Co. Version 2.6.0";
8
9#include <stdio.h>
10#if HAVE_SYS_TYPES_H
11# include <sys/types.h>
12#endif
13#if HAVE_SYS_STAT_H
14# include <sys/stat.h>
15#endif
16#if STDC_HEADERS
17# include <stdlib.h>
18# include <stddef.h>
19#else
20# if HAVE_STDLIB_H
21#  include <stdlib.h>
22# endif
23#endif
24#if HAVE_STRING_H
25# if !STDC_HEADERS && HAVE_MEMORY_H
26#  include <memory.h>
27# endif
28# include <string.h>
29#endif
30#if HAVE_STRINGS_H
31# include <strings.h>
32#endif
33#if HAVE_INTTYPES_H
34# include <inttypes.h>
35#else
36# if HAVE_STDINT_H
37#  include <stdint.h>
38# endif
39#endif
40#if HAVE_UNISTD_H
41# include <unistd.h>
42#endif
43#if HAVE_SYS_IOCTL_H
44# include <sys/ioctl.h>
45#endif
46#if HAVE_SCHED_H
47# include <sched.h>
48#endif
49
50#include <fcntl.h>
51#ifndef WIN32
52#include <errno.h>
53#include <signal.h>
54#endif
55
56#if TIME_WITH_SYS_TIME
57# include <sys/time.h>
58# include <time.h>
59#else
60# if HAVE_SYS_TIME_H
61#  include <sys/time.h>
62# else
63#  include <time.h>
64# endif
65#endif
66
67#include <ctype.h>
68
69#ifdef NOSTDLIBH
70#include <malloc.h>
71#endif /* NOSTDLIBH */
72
73#include <assert.h>
74
75#ifndef WIN32
76#include <sys/socket.h>
77#include <netinet/in.h>
78
79/* it would seem that including both <netinet/tcp.h> and <linux/tcp.h>
80   is not a path to happiness and joy when one wishes to grab tcp_info
81   stats and not get something like the compiler complaining about
82   either redefinitions, or missing tcpi_total_retrans. */
83#ifdef HAVE_LINUX_TCP_H
84#include <linux/tcp.h>
85#else
86#include <netinet/tcp.h>
87#endif
88
89/* this is to get us the definition of MSG_FASTOPEN. we may need to
90   cheat just a litle at first */
91#ifdef HAVE_LINUX_SOCKET_H
92# include <linux/socket.h>
93# ifndef MSG_FASTOPEN
94#  warning Using our own value for MSG_FASTOPEN
95#  define MSG_FASTOPEN	0x20000000	/* Send data in TCP SYN */
96# endif
97# ifndef TCP_FASTOPEN
98#  warning Using our own value for TCP_FASTOPEN
99#  define TCP_FASTOPEN 23
100# endif
101#endif
102
103#ifdef HAVE_NETINET_SCTP_H
104#include <netinet/sctp.h>
105#endif
106
107#include <arpa/inet.h>
108#include <netdb.h>
109#else /* WIN32 */
110#include <process.h>
111#define netperf_socklen_t socklen_t
112#include <winsock2.h>
113/* while it is unlikely that anyone running Windows 2000 or NT 4 is
114   going to be trying to compile this, if they are they will want to
115   define DONT_IPV6 in the sources file */
116#ifndef DONT_IPV6
117#include <ws2tcpip.h>
118#endif
119#include <windows.h>
120
121#define sleep(x) Sleep((x)*1000)
122
123#include "missing\stdint.h"
124#endif /* WIN32 */
125
126/* We don't want to use bare constants in the shutdown() call.  In the
127   extremely unlikely event that SHUT_WR isn't defined, we will define
128   it to the value we used to be passing to shutdown() anyway.  raj
129   2007-02-08 */
130#if !defined(SHUT_WR)
131#define SHUT_WR 1
132#endif
133
134#if !defined(HAVE_GETADDRINFO) || !defined(HAVE_GETNAMEINFO)
135# include "missing/getaddrinfo.h"
136#endif
137
138#include "netlib.h"
139#include "netsh.h"
140#include "nettest_bsd.h"
141
142/* we only really use this once, but the initial patch to
143   src/nettest_bsd.c used it in several places. keep it as a macro
144   just for kicks and just in case we do end-up needing to use it
145   multiple times. */
146
147#define WAIT_BEFORE_DATA_TRAFFIC() \
148{ \
149  if (wait_time_secs) \
150    sleep(wait_time_secs); \
151} \
152
153
154/* since someone can ask for latency stats, we will always include
155   this and do the other other things */
156#include "hist.h"
157
158static HIST time_hist;
159
160
161
162#ifdef WANT_INTERVALS
163int interval_count;
164unsigned int interval_wait_microseconds;
165
166/* hoist the timestamps up here so we can use them to factor-out the
167   time spent "waiting" */
168/* first out timestamp */
169#ifdef HAVE_GETHRTIME
170static hrtime_t intvl_one;
171static hrtime_t intvl_two;
172static hrtime_t intvl_wait_start;
173static hrtime_t *intvl_one_ptr = &intvl_one;
174static hrtime_t *intvl_two_ptr = &intvl_two;
175static hrtime_t *temp_intvl_ptr = &intvl_one;
176#elif defined(WIN32)
177static LARGE_INTEGER intvl_one;
178static LARGE_INTEGER intvl_two;
179static LARGE_INTEGER intvl_wait_start;
180static LARGE_INTEGER *intvl_one_ptr = &intvl_one;
181static LARGE_INTEGER *intvl_two_ptr = &intvl_two;
182static LARGE_INTEGER *temp_intvl_ptr = &intvl_one;
183#else
184static struct timeval intvl_one;
185static struct timeval intvl_two;
186static struct timeval intvl_wait_start;
187static struct timeval *intvl_one_ptr = &intvl_one;
188static struct timeval *intvl_two_ptr = &intvl_two;
189static struct timeval *temp_intvl_ptr = &intvl_one;
190#endif
191
192#ifndef WANT_SPIN
193#ifdef WIN32
194#define INTERVALS_INIT() \
195    if (interval_burst) { \
196      /* zero means that we never pause, so we never should need the \
197         interval timer. we used to use it for demo mode, but we deal \
198	 with that with a variant on watching the clock rather than \
199	 waiting for a timer. raj 2006-02-06 */ \
200      start_itimer(interval_wate); \
201    } \
202    interval_count = interval_burst; \
203    interval_wait_microseconds = 0;
204#else
205sigset_t signal_set;
206#define INTERVALS_INIT() \
207    if (interval_burst) { \
208      /* zero means that we never pause, so we never should need the \
209         interval timer. we used to use it for demo mode, but we deal \
210	 with that with a variant on watching the clock rather than \
211	 waiting for a timer. raj 2006-02-06 */ \
212      start_itimer(interval_wate); \
213    } \
214    interval_count = interval_burst; \
215    interval_wait_microseconds = 0; \
216    /* get the signal set for the call to sigsuspend */ \
217    if (sigprocmask(SIG_BLOCK, (sigset_t *)NULL, &signal_set) != 0) { \
218      fprintf(where, \
219	      "%s: unable to get sigmask errno %d\n", \
220	      __FUNCTION__, \
221	      errno); \
222      fflush(where); \
223      exit(1); \
224    }
225#endif /* WIN32 */
226
227#ifdef WIN32
228#define INTERVALS_WAIT() \
229      /* in this case, the interval count is the count-down counter \
230	 to decide to sleep for a little bit */ \
231      if ((interval_burst) && (--interval_count == 0)) { \
232	/* call WaitForSingleObject and wait for the interval timer to get us \
233	   out */ \
234	if (debug > 1) { \
235	  fprintf(where,"about to suspend\n"); \
236	  fflush(where); \
237	} \
238        HIST_timestamp(&intvl_wait_start); \
239    if (WaitForSingleObject(WinTimer, INFINITE) != WAIT_OBJECT_0) { \
240        fprintf(where, "WaitForSingleObject failed (%d)\n", GetLastError()); \
241	  fflush(where); \
242	  exit(1); \
243	} \
244        HIST_timestamp(&intvl_two); \
245        interval_wait_microseconds += \
246          delta_micro(&intvl_wait_start,&intvl_two); \
247	interval_count = interval_burst; \
248      }
249#else
250#define INTERVALS_WAIT() \
251      /* in this case, the interval count is the count-down couter \
252	 to decide to sleep for a little bit */ \
253      if ((interval_burst) && (--interval_count == 0)) { \
254	/* call sigsuspend and wait for the interval timer to get us \
255	   out */ \
256	if (debug > 1) { \
257	  fprintf(where,"about to suspend\n"); \
258	  fflush(where); \
259	} \
260        HIST_timestamp(&intvl_wait_start); \
261	if (sigsuspend(&signal_set) == EFAULT) { \
262	  fprintf(where, \
263		  "%s: fault with sigsuspend.\n", \
264                  __FUNCTION__); \
265	  fflush(where); \
266	  exit(1); \
267	} \
268        HIST_timestamp(&intvl_two); \
269        interval_wait_microseconds += \
270          delta_micro(&intvl_wait_start,&intvl_two); \
271	interval_count = interval_burst; \
272      }
273#endif /* WIN32 */
274#else
275
276#define INTERVALS_INIT() \
277      if (interval_burst) { \
278	HIST_timestamp(intvl_one_ptr); \
279      } \
280      interval_wait_microseconds = 0; \
281      interval_count = interval_burst; \
282
283#define INTERVALS_WAIT() \
284      /* in this case, the interval count is the count-down couter \
285	 to decide to sleep for a little bit */ \
286      if ((interval_burst) && (--interval_count == 0)) { \
287	/* spin and wait for the interval timer to get us \
288	   out */ \
289	if (debug > 1) { \
290	  fprintf(where,"about to spin suspend\n"); \
291	  fflush(where); \
292	} \
293        \
294        HIST_timestamp(&intvl_wait_start); \
295        do { \
296          HIST_timestamp(intvl_two_ptr); } \
297        while(delta_micro(intvl_one_ptr,intvl_two_ptr) < interval_usecs); \
298        interval_wait_microseconds += \
299          delta_micro(&intvl_wait_start,&intvl_two); \
300	temp_intvl_ptr = intvl_one_ptr; \
301	intvl_one_ptr = intvl_two_ptr; \
302	intvl_two_ptr = temp_intvl_ptr; \
303	interval_count = interval_burst; \
304      }
305#endif
306#endif
307
308#define NETPERF_WAITALL 0x1
309
310extern void get_uuid_string(char *string, size_t size);
311
312/* a boatload of globals while I settle things out */
313char *output_selection_spec = NULL;
314
315char test_uuid[38];
316
317double result_confid_pct = -1.0;
318double loc_cpu_confid_pct = -1.0;
319double rem_cpu_confid_pct = -1.0;
320double interval_pct = -1.0;
321
322int protocol;
323int direction;
324int remote_send_size = -1;
325int remote_recv_size = -1;
326int remote_send_size_req = -1;
327int remote_recv_size_req = -1;
328int remote_use_sendfile;
329
330extern int loc_dirty_count;
331extern int loc_clean_count;
332extern int rem_dirty_count;
333extern int rem_clean_count;
334int remote_checksum_off;
335int connection_test;
336int dont_give_up = 0;
337int use_fastopen = 0;
338int use_write = 0;
339int need_to_connect;
340int need_connection;
341int bytes_to_send;
342double bytes_per_send;
343int failed_sends;
344int bytes_to_recv;
345double bytes_per_recv;
346int null_message_ok = 0;
347
348int was_legacy = 0;
349int legacy = 0;
350int implicit_direction = 0;
351int explicit_data_address = 0;
352int want_defer_accept = 0;
353
354uint64_t      trans_completed = 0;
355int64_t       units_remaining;
356uint64_t      bytes_sent = 0;
357uint64_t      bytes_received = 0;
358uint64_t      local_send_calls = 0;
359uint64_t      local_receive_calls = 0;
360uint64_t      remote_bytes_sent;
361uint64_t      remote_bytes_received;
362uint64_t      remote_send_calls;
363uint64_t      remote_receive_calls;
364double        bytes_xferd;
365double        remote_bytes_xferd;
366double        remote_bytes_per_recv;
367double        remote_bytes_per_send;
368float         elapsed_time;
369float         local_cpu_utilization;
370float	      local_service_demand;
371float         remote_cpu_utilization;
372float	      remote_service_demand;
373double	      thruput;
374double        local_send_thruput;
375double        local_recv_thruput;
376double        remote_send_thruput;
377double        remote_recv_thruput;
378
379/* kludges for omni output */
380double      elapsed_time_double;
381double      local_service_demand_double;
382double      remote_service_demand_double;
383double      transaction_rate = 1.0;
384double      rtt_latency = -1.0;
385int32_t     transport_mss = -2;
386int32_t     local_transport_retrans = -2;
387int32_t     remote_transport_retrans = -2;
388char        *deprecated_str = "Deprecated";
389int         remote_interface_vendor = -2;
390int         remote_interface_device = -2;
391int         remote_interface_subvendor = -2;
392int         remote_interface_subdevice = -2;
393int         local_interface_vendor = -2;
394int         local_interface_device = -2;
395int         local_interface_subvendor = -2;
396int         local_interface_subdevice = -2;
397int         local_cpu_frequency = 0;
398int         remote_cpu_frequency = 0;
399
400int         local_security_type_id;
401int         local_security_enabled_num;
402int         remote_security_type_id;
403int         remote_security_enabled_num;
404
405char        local_cong_control[16] = "";
406char        remote_cong_control[16] = "";
407char        local_cong_control_req[16] = "";
408char        remote_cong_control_req[16] = "";
409
410int         receive_timeout = -1;
411
412/* new statistics based on code diffs from Google, with raj's own
413   personal twist added to make them compatible with the omni
414   tests... 20100913 */
415
416/* min and max "latency" */
417int         min_latency = -1, max_latency = -1;
418/* the percentiles */
419int         p50_latency = -1, p90_latency = -1, p99_latency = -1;
420/* mean and stddev - while the mean is reduntant with the *_RR test we
421   keep it because it won't be for other tests */
422double      mean_latency = -1.0, stddev_latency = -1.0;
423
424/* default to zero to avoid randomizing */
425int local_mask_len = 0;
426int remote_mask_len = 0;
427
428int printing_initialized = 0;
429
430char *sd_str;
431char *thruput_format_str;
432
433char *socket_type_str;
434char *protocol_str;
435char *direction_str;
436
437extern int first_burst_size;
438
439int  parallel_connections = 1;
440
441static int socket_debug = 0;
442
443#if defined(HAVE_SENDFILE) && (defined(__linux) || defined(__sun))
444#include <sys/sendfile.h>
445#endif /* HAVE_SENDFILE && (__linux || __sun) */
446
447static int confidence_iteration;
448
449static  int local_cpu_method;
450static  int remote_cpu_method;
451
452/* these will control the width of port numbers we try to use in the */
453/* TCP_CRR and/or TCP_TRR tests. raj 3/95 */
454static int client_port_min = 5000;
455static int client_port_max = 65535;
456
457 /* different options for the sockets				*/
458
459int
460  loc_nodelay,		/* don't/do use NODELAY	locally		*/
461  rem_nodelay,		/* don't/do use NODELAY remotely	*/
462  loc_sndavoid,		/* avoid send copies locally		*/
463  loc_rcvavoid,		/* avoid recv copies locally		*/
464  rem_sndavoid,		/* avoid send copies remotely		*/
465  rem_rcvavoid; 	/* avoid recv_copies remotely		*/
466
467extern int
468  loc_tcpcork,
469  rem_tcpcork,
470  local_connected,
471  remote_connected;
472
473enum netperf_output_type {
474  NETPERF_TYPE_UNKNOWN,
475  NETPERF_TYPE_UINT32,
476  NETPERF_TYPE_INT32,
477  NETPERF_TYPE_UINT64,
478  NETPERF_TYPE_INT64,
479  NETPERF_TYPE_CHAR,
480  NETPERF_TYPE_FLOAT,
481  NETPERF_TYPE_DOUBLE,
482};
483
484/* you should add to this in the order in which they should appear in
485   the default csv (everything) output */
486
487enum netperf_output_name {
488  NETPERF_OUTPUT_UNKNOWN,
489  OUTPUT_NONE,
490  SOCKET_TYPE,
491  PROTOCOL,
492  DIRECTION,
493  ELAPSED_TIME,
494  THROUGHPUT,
495  THROUGHPUT_UNITS,
496  LSS_SIZE_REQ,
497  LSS_SIZE,
498  LSS_SIZE_END,
499  LSR_SIZE_REQ,
500  LSR_SIZE,
501  LSR_SIZE_END,
502  RSS_SIZE_REQ,
503  RSS_SIZE,
504  RSS_SIZE_END,
505  RSR_SIZE_REQ,
506  RSR_SIZE,
507  RSR_SIZE_END,
508  LOCAL_SEND_SIZE,
509  LOCAL_RECV_SIZE,
510  REMOTE_SEND_SIZE,
511  REMOTE_RECV_SIZE,
512  REQUEST_SIZE,
513  RESPONSE_SIZE,
514  LOCAL_CPU_UTIL,
515  LOCAL_CPU_PERCENT_USER,
516  LOCAL_CPU_PERCENT_SYSTEM,
517  LOCAL_CPU_PERCENT_IOWAIT,
518  LOCAL_CPU_PERCENT_IRQ,
519  LOCAL_CPU_PERCENT_SWINTR,
520  LOCAL_CPU_METHOD,
521  LOCAL_SD,
522  REMOTE_CPU_UTIL,
523  REMOTE_CPU_PERCENT_USER,
524  REMOTE_CPU_PERCENT_SYSTEM,
525  REMOTE_CPU_PERCENT_IOWAIT,
526  REMOTE_CPU_PERCENT_IRQ,
527  REMOTE_CPU_PERCENT_SWINTR,
528  REMOTE_CPU_METHOD,
529  REMOTE_SD,
530  SD_UNITS,
531  CONFIDENCE_LEVEL,
532  CONFIDENCE_INTERVAL,
533  CONFIDENCE_ITERATION,
534  THROUGHPUT_CONFID,
535  LOCAL_CPU_CONFID,
536  REMOTE_CPU_CONFID,
537  TRANSACTION_RATE,
538  RT_LATENCY,
539  BURST_SIZE,
540  LOCAL_TRANSPORT_RETRANS,
541  REMOTE_TRANSPORT_RETRANS,
542  TRANSPORT_MSS,
543  LOCAL_SEND_THROUGHPUT,
544  LOCAL_RECV_THROUGHPUT,
545  REMOTE_SEND_THROUGHPUT,
546  REMOTE_RECV_THROUGHPUT,
547  LOCAL_CPU_BIND,
548  LOCAL_CPU_COUNT,
549  LOCAL_CPU_PEAK_UTIL,
550  LOCAL_CPU_PEAK_ID,
551  LOCAL_CPU_MODEL,
552  LOCAL_CPU_FREQUENCY,
553  REMOTE_CPU_BIND,
554  REMOTE_CPU_COUNT,
555  REMOTE_CPU_PEAK_UTIL,
556  REMOTE_CPU_PEAK_ID,
557  REMOTE_CPU_MODEL,
558  REMOTE_CPU_FREQUENCY,
559  SOURCE_PORT,
560  SOURCE_ADDR,
561  SOURCE_FAMILY,
562  DEST_PORT,
563  DEST_ADDR,
564  DEST_FAMILY,
565  LOCAL_SEND_CALLS,
566  LOCAL_RECV_CALLS,
567  LOCAL_BYTES_PER_RECV,
568  LOCAL_BYTES_PER_SEND,
569  LOCAL_BYTES_SENT,
570  LOCAL_BYTES_RECVD,
571  LOCAL_BYTES_XFERD,
572  LOCAL_SEND_OFFSET,
573  LOCAL_RECV_OFFSET,
574  LOCAL_SEND_ALIGN,
575  LOCAL_RECV_ALIGN,
576  LOCAL_SEND_WIDTH,
577  LOCAL_RECV_WIDTH,
578  LOCAL_SEND_DIRTY_COUNT,
579  LOCAL_RECV_DIRTY_COUNT,
580  LOCAL_RECV_CLEAN_COUNT,
581  LOCAL_NODELAY,
582  LOCAL_CORK,
583  REMOTE_SEND_CALLS,
584  REMOTE_RECV_CALLS,
585  REMOTE_BYTES_PER_RECV,
586  REMOTE_BYTES_PER_SEND,
587  REMOTE_BYTES_SENT,
588  REMOTE_BYTES_RECVD,
589  REMOTE_BYTES_XFERD,
590  REMOTE_SEND_OFFSET,
591  REMOTE_RECV_OFFSET,
592  REMOTE_SEND_ALIGN,
593  REMOTE_RECV_ALIGN,
594  REMOTE_SEND_WIDTH,
595  REMOTE_RECV_WIDTH,
596  REMOTE_SEND_DIRTY_COUNT,
597  REMOTE_RECV_DIRTY_COUNT,
598  REMOTE_RECV_CLEAN_COUNT,
599  REMOTE_NODELAY,
600  REMOTE_CORK,
601  LOCAL_SYSNAME,
602  LOCAL_SYSTEM_MODEL,
603  LOCAL_RELEASE,
604  LOCAL_VERSION,
605  LOCAL_MACHINE,
606  REMOTE_SYSNAME,
607  REMOTE_SYSTEM_MODEL,
608  REMOTE_RELEASE,
609  REMOTE_VERSION,
610  REMOTE_MACHINE,
611  LOCAL_INTERFACE_NAME,
612  LOCAL_INTERFACE_VENDOR,
613  LOCAL_INTERFACE_DEVICE,
614  LOCAL_INTERFACE_SUBVENDOR,
615  LOCAL_INTERFACE_SUBDEVICE,
616  LOCAL_DRIVER_NAME,
617  LOCAL_DRIVER_VERSION,
618  LOCAL_DRIVER_FIRMWARE,
619  LOCAL_DRIVER_BUS,
620  LOCAL_INTERFACE_SLOT,
621  REMOTE_INTERFACE_NAME,
622  REMOTE_INTERFACE_VENDOR,
623  REMOTE_INTERFACE_DEVICE,
624  REMOTE_INTERFACE_SUBVENDOR,
625  REMOTE_INTERFACE_SUBDEVICE,
626  REMOTE_DRIVER_NAME,
627  REMOTE_DRIVER_VERSION,
628  REMOTE_DRIVER_FIRMWARE,
629  REMOTE_DRIVER_BUS,
630  REMOTE_INTERFACE_SLOT,
631  LOCAL_INTERVAL_USECS,
632  LOCAL_INTERVAL_BURST,
633  REMOTE_INTERVAL_USECS,
634  REMOTE_INTERVAL_BURST,
635  LOCAL_SECURITY_TYPE_ID,
636  LOCAL_SECURITY_TYPE,
637  LOCAL_SECURITY_ENABLED_NUM,
638  LOCAL_SECURITY_ENABLED,
639  LOCAL_SECURITY_SPECIFIC,
640  REMOTE_SECURITY_TYPE_ID,
641  REMOTE_SECURITY_TYPE,
642  REMOTE_SECURITY_ENABLED_NUM,
643  REMOTE_SECURITY_ENABLED,
644  REMOTE_SECURITY_SPECIFIC,
645  RESULT_BRAND,
646  UUID,
647  MIN_LATENCY,
648  MAX_LATENCY,
649  P50_LATENCY,
650  P90_LATENCY,
651  P99_LATENCY,
652  MEAN_LATENCY,
653  STDDEV_LATENCY,
654  LOCAL_SOCKET_PRIO,
655  REMOTE_SOCKET_PRIO,
656  LOCAL_SOCKET_TOS,
657  REMOTE_SOCKET_TOS,
658  LOCAL_CONG_CONTROL,
659  REMOTE_CONG_CONTROL,
660  LOCAL_FILL_FILE,
661  REMOTE_FILL_FILE,
662  COMMAND_LINE,    /* COMMAND_LINE should always be "last" */
663  OUTPUT_END,
664  NETPERF_OUTPUT_MAX
665};
666
667/* flags for the output groups, lower 16 bits for remote, upper 16
668   bits for local */
669
670#define OMNI_WANT_REM_IFNAME  0X00000001
671#define OMNI_WANT_LOC_IFNAME  0X00010000
672#define OMNI_WANT_REM_IFSLOT  0X00000002
673#define OMNI_WANT_LOC_IFSLOT  0X00020000
674#define OMNI_WANT_REM_IFIDS   0X00000004
675#define OMNI_WANT_LOC_IFIDS   0X00040000
676#define OMNI_WANT_REM_DRVINFO 0X00000008
677#define OMNI_WANT_LOC_DRVINFO 0X00080000
678#define OMNI_WANT_STATS       0X00100010
679#define OMNI_WANT_REM_CONG    0X00000020
680#define OMNI_WANT_LOC_CONG    0X00200000
681
682unsigned int desired_output_groups = 0;
683
684typedef struct netperf_output_elt {
685  enum netperf_output_name output_name;  /* belt and suspenders */
686  int max_line_len; /* length of the longest of the "lines" */
687  int tot_line_len; /* total length of all lines, including spaces */
688  char *line[4];
689  char *format;        /* format to apply to value */
690  void *display_value; /* where to find the value */
691  enum netperf_output_type output_type; /* what type is the value? */
692  int  output_default; /* is it included in the default output */
693  unsigned int output_group; /* used to avoid some lookups */
694} netperf_output_elt_t;
695
696netperf_output_elt_t netperf_output_source[NETPERF_OUTPUT_MAX];
697
698#define NETPERF_MAX_BLOCKS 4
699
700/* let us simply use one, two-dimensional list, and either use or some
701   of the additional dimension depending on the type of output we are
702   doing.  this should help simplify matters. raj 20110120 */
703
704enum netperf_output_name output_list[NETPERF_MAX_BLOCKS][NETPERF_OUTPUT_MAX];
705
706/* some things for setting the source IP address on outgoing UDP
707   sends. borrows liberally from
708   http://stackoverflow.com/questions/3062205/setting-the-source-ip-for-a-udp-socket */
709
710int want_use_pktinfo = 0;
711int use_pktinfo = 0;
712int have_pktinfo = 0;
713#ifdef IP_PKTINFO
714struct in_pktinfo in_pktinfo;
715#endif
716
717char *direction_to_str(int direction) {
718  if (NETPERF_RECV_ONLY(direction)) return "Receive";
719  if (NETPERF_XMIT_ONLY(direction)) return "Send";
720  if (NETPERF_CC(direction)) return "Connection";
721  else if (connection_test) {
722    return "Connect|Send|Recv";
723  }
724  else return "Send|Recv";
725}
726
727static unsigned short
728get_port_number(struct addrinfo *res)
729{
730  switch(res->ai_family) {
731  case AF_INET: {
732    struct sockaddr_in *foo = (struct sockaddr_in *)res->ai_addr;
733    return(ntohs(foo->sin_port));
734    break;
735  }
736#if defined(AF_INET6)
737  case AF_INET6: {
738    struct sockaddr_in6 *foo = (struct sockaddr_in6 *)res->ai_addr;
739    return(ntohs(foo->sin6_port));
740    break;
741  }
742#endif
743  default:
744    fprintf(where,
745	    "Unexpected Address Family %u\n",res->ai_family);
746    fflush(where);
747    exit(-1);
748  }
749}
750
751/* does this need to become conditional on the presence of the macros
752   or might we ass-u-me that we will not be compiled on something so
753   old as to not have what we use? raj 20090803 */
754static int
755is_multicast_addr(struct addrinfo *res) {
756  switch(res->ai_family) {
757  case AF_INET: {
758    /* IPv4 multicast runs from 224.0.0.0 to 239.255.255.255 or
759       0xE0000000 to 0xEFFFFFFF. Thankfully though there are macros
760       available to make the checks for one */
761    struct in_addr bar = ((struct sockaddr_in *)res->ai_addr)->sin_addr;
762    /* and here I thought IN_MULTICAST would operate on things in
763       network byte order???  raj 20100315 */
764    return IN_MULTICAST(ntohl(bar.s_addr));
765  }
766#if defined(AF_INET6)
767  case AF_INET6: {
768    struct in6_addr *bar = &(((struct sockaddr_in6 *)res->ai_addr)->sin6_addr);
769    return IN6_IS_ADDR_MULTICAST(bar);
770  }
771#endif
772  default:
773    fprintf(where,
774	    "Unexpected Address Family for Multicast Check %u\n",
775	    res->ai_family);
776    fflush(where);
777    return 0;  /* or should we exit? */
778  }
779}
780
781static void
782set_multicast_ttl(SOCKET sock) {
783  int optlen = sizeof(int);
784
785  /* now set/get the TTL */
786  if (multicast_ttl >= 0) {
787    if (setsockopt(sock,
788		   IPPROTO_IP,
789#if defined(IP_MULTICAST_TTL)
790		   IP_MULTICAST_TTL,
791#else
792		   IP_TTL,
793#endif
794		   (const char *)&multicast_ttl,
795		   sizeof(multicast_ttl)) == SOCKET_ERROR) {
796      fprintf(where,
797	      "setsockopt(IP_TTL) failed errno %d\n",
798	      errno);
799    }
800  }
801  if (getsockopt(sock,
802		 IPPROTO_IP,
803		 IP_TTL,
804		 (char *)&multicast_ttl,
805		 (netperf_socklen_t *)&optlen) < 0) {
806    fprintf(where,
807	    "getsockopt(IP_TTL) failed errno %d\n",
808	    errno);
809    multicast_ttl = -2;
810  }
811}
812
813/* we presume we are only called with something which is actually a
814   multicast address. raj 20100315 */
815static void
816join_multicast_addr(SOCKET sock, struct addrinfo *res) {
817  switch(res->ai_family) {
818  case AF_INET: {
819    struct ip_mreq mreq;
820    struct in_addr bar = ((struct sockaddr_in *)res->ai_addr)->sin_addr;
821    int optlen = sizeof(int);
822    int one    = 1;
823
824    mreq.imr_multiaddr.s_addr=bar.s_addr;
825    mreq.imr_interface.s_addr=htonl(INADDR_ANY);
826    if (setsockopt(sock,
827		   IPPROTO_IP,
828		   IP_ADD_MEMBERSHIP,
829		   (const char *)&mreq,
830		   sizeof(mreq)) == 0) {
831
832      /* let others do the same */
833      if (setsockopt(sock,
834		     SOL_SOCKET,
835		     SO_REUSEADDR,
836		     (const char *)&one,
837		     sizeof(one)) == SOCKET_ERROR) {
838	if (debug) {
839	  fprintf(where,
840		  "join_multicast_addr SO_REUSADDR failed errno %d\n",
841		  errno);
842	  fflush(where);
843	}
844      }
845
846      /* now set/get the TTL */
847      if (multicast_ttl >= 0) {
848	if (setsockopt(sock,
849		       IPPROTO_IP,
850		       IP_TTL,
851		       (const char *)&multicast_ttl,
852		       sizeof(multicast_ttl)) == SOCKET_ERROR) {
853	  fprintf(where,
854		  "setsockopt(IP_TTL) failed errno %d\n",
855		  errno);
856	}
857      }
858      if (getsockopt(sock,
859		     IPPROTO_IP,
860		     IP_TTL,
861		     (char *)&multicast_ttl,
862		     (netperf_socklen_t *)&optlen) == SOCKET_ERROR) {
863	fprintf(where,
864		"getsockopt(IP_TTL) failed errno %d\n",
865		errno);
866	multicast_ttl = -2;
867      }
868    }
869    else {
870      if (debug) {
871	fprintf(where,
872		"setsockopt(IP_ADD_MEMBERSHIP) failed errno %d\n",
873		errno);
874	fflush(where);
875      }
876    }
877    break;
878  }
879  case AF_INET6: {
880    fprintf(where,"I do not know how to join an IPv6 multicast group\n");
881    break;
882  }
883
884  }
885  return;
886}
887
888static void
889extract_inet_address_and_port(struct addrinfo *res, void *addr, int len, int *port)
890{
891 switch(res->ai_family) {
892  case AF_INET: {
893    struct sockaddr_in *foo = (struct sockaddr_in *)res->ai_addr;
894    *port = foo->sin_port;
895    memcpy(addr,&(foo->sin_addr),min(len,sizeof(foo->sin_addr)));
896    break;
897  }
898#if defined(AF_INET6)
899  case AF_INET6: {
900    struct sockaddr_in6 *foo = (struct sockaddr_in6 *)res->ai_addr;
901    *port = foo->sin6_port;
902    memcpy(addr,&(foo->sin6_addr),min(len,sizeof(foo->sin6_addr)));
903    break;
904  }
905#endif
906  default:
907    *port = 0xDEADBEEF;
908    strncpy(addr,"UNKN FAMILY",len);
909  }
910}
911
912void
913pick_next_port_number(struct addrinfo *local_res, struct addrinfo *remote_res) {
914
915  static int myport_init = 0;
916  static unsigned short myport = 0;
917
918  if (0 == myport_init)  {
919    /* pick a nice random spot between client_port_min and
920       client_port_max for our initial port number, but only for a
921       connection oriented test. otherwise, we will want to set myport
922       to a specific port provided by the user if they have so provided
923       a specific port :)  raj 2008-01-08 */
924    srand(getpid());
925    if (client_port_max - client_port_min) {
926      myport = client_port_min +
927	(rand() % (client_port_max - client_port_min));
928    }
929    else {
930      myport = (unsigned short)client_port_min;
931    }
932    /* there will be a ++ before the first call to bind, so subtract one */
933    myport--;
934    myport_init = 1;
935  }
936
937  /* newport: */
938  /* pick a new port number */
939  myport++;
940
941  /* check to see if we are using the port number on which the
942     server is sitting _before_ we check against the boundaries lest
943     the server sits at the upper boundary. if this happens to be a
944     loopback test, trying to use the same portnumber would lead to
945     unsatisfying results and should be avoided.  if this isn't a
946     loopback test, avoiding using the same port number doesn't
947     seriously affect anything anyway */
948
949  if (myport == get_port_number(remote_res)) myport++;
950
951  /* wrap the port number when we reach the upper bound.  for
952     students of networking history, some ancient stacks (1980's and
953     early 1990's perhaps) mistakenly treated these port numbers as
954     signed 16 bit quantities.  we make no effort here to support
955     such stacks. raj 2008-01-08 */
956  if (myport >= client_port_max) {
957    myport = (unsigned short)client_port_min;
958  }
959
960  /* set up the data socket */
961  set_port_number(local_res, (unsigned short)myport);
962}
963
964/* at some point this should become a table lookup... raj 20090813 */
965char *
966netperf_output_enum_to_str(enum netperf_output_name output_name)
967{
968  switch (output_name) {
969  case OUTPUT_NONE:
970    return "OUTPUT_NONE";
971  case   COMMAND_LINE:
972    return "COMMAND_LINE";
973  case UUID:
974    return "UUID";
975  case RESULT_BRAND:
976    return "RESULT_BRAND";
977  case   SOCKET_TYPE:
978    return "SOCKET_TYPE";
979  case   DIRECTION:
980    return "DIRECTION";
981  case   PROTOCOL:
982    return "PROTOCOL";
983  case   ELAPSED_TIME:
984    return "ELAPSED_TIME";
985  case   SOURCE_PORT:
986    return "SOURCE_PORT";
987  case   SOURCE_ADDR:
988    return "SOURCE_ADDR";
989  case SOURCE_FAMILY:
990    return "SOURCE_FAMILY";
991  case   DEST_PORT:
992    return "DEST_PORT";
993  case   DEST_ADDR:
994    return "DEST_ADDR";
995  case DEST_FAMILY:
996    return "DEST_FAMILY";
997  case THROUGHPUT:
998    return "THROUGHPUT";
999  case LOCAL_SEND_THROUGHPUT:
1000    return "LOCAL_SEND_THROUGHPUT";
1001  case LOCAL_RECV_THROUGHPUT:
1002    return "LOCAL_RECV_THROUGHPUT";
1003  case REMOTE_SEND_THROUGHPUT:
1004    return "REMOTE_SEND_THROUGHPUT";
1005  case REMOTE_RECV_THROUGHPUT:
1006    return "REMOTE_RECV_THROUGHPUT";
1007  case THROUGHPUT_UNITS:
1008    return "THROUGHPUT_UNITS";
1009  case CONFIDENCE_LEVEL:
1010    return "CONFIDENCE_LEVEL";
1011  case CONFIDENCE_INTERVAL:
1012    return "CONFIDENCE_INTERVAL";
1013  case CONFIDENCE_ITERATION:
1014    return "CONFIDENCE_ITERATION";
1015  case THROUGHPUT_CONFID:
1016    return "THROUGHPUT_CONFID";
1017  case LOCAL_CPU_CONFID:
1018    return "LOCAL_CPU_CONFID";
1019  case REMOTE_CPU_CONFID:
1020    return "REMOTE_CPU_CONFID";
1021  case RT_LATENCY:
1022    return "RT_LATENCY";
1023  case TRANSACTION_RATE:
1024    return "TRANSACTION_RATE";
1025  case BURST_SIZE:
1026    return "BURST_SIZE";
1027  case LOCAL_TRANSPORT_RETRANS:
1028    return "LOCAL_TRANSPORT_RETRANS";
1029  case REMOTE_TRANSPORT_RETRANS:
1030    return "REMOTE_TRANSPORT_RETRANS";
1031  case TRANSPORT_MSS:
1032    return "TRANSPORT_MSS";
1033  case REQUEST_SIZE:
1034    return "REQUEST_SIZE";
1035  case RESPONSE_SIZE:
1036    return "RESPONSE_SIZE";
1037  case   LSS_SIZE_REQ:
1038    return "LSS_SIZE_REQ";
1039  case   LSS_SIZE:
1040    return "LSS_SIZE";
1041  case   LSS_SIZE_END:
1042    return "LSS_SIZE_END";
1043  case   LSR_SIZE_REQ:
1044    return "LSR_SIZE_REQ";
1045  case   LSR_SIZE:
1046    return "LSR_SIZE";
1047  case   LSR_SIZE_END:
1048    return "LSR_SIZE_END";
1049  case   LOCAL_SEND_SIZE:
1050    return "LOCAL_SEND_SIZE";
1051  case   LOCAL_RECV_SIZE:
1052    return "LOCAL_RECV_SIZE";
1053  case   LOCAL_SEND_CALLS:
1054    return "LOCAL_SEND_CALLS";
1055  case   LOCAL_RECV_CALLS:
1056    return "LOCAL_RECV_CALLS";
1057  case   LOCAL_BYTES_PER_RECV:
1058    return "LOCAL_BYTES_PER_RECV";
1059  case   LOCAL_BYTES_PER_SEND:
1060    return "LOCAL_BYTES_PER_SEND";
1061  case   LOCAL_BYTES_SENT:
1062    return "LOCAL_BYTES_SENT";
1063  case   LOCAL_BYTES_RECVD:
1064    return "LOCAL_BYTES_RECVD";
1065  case   LOCAL_BYTES_XFERD:
1066    return "LOCAL_BYTES_XFERD";
1067  case LOCAL_SEND_OFFSET:
1068    return "LOCAL_SEND_OFFSET";
1069  case LOCAL_RECV_OFFSET:
1070    return "LOCAL_RECV_OFFSET";
1071  case LOCAL_RECV_ALIGN:
1072    return "LOCAL_RECV_ALIGN";
1073  case LOCAL_SEND_ALIGN:
1074    return "LOCAL_SEND_ALIGN";
1075  case LOCAL_SEND_WIDTH:
1076    return "LOCAL_SEND_WIDTH";
1077  case LOCAL_RECV_WIDTH:
1078    return "LOCAL_RECV_WIDTH";
1079  case   LOCAL_SEND_DIRTY_COUNT:
1080    return "LOCAL_SEND_DIRTY_COUNT";
1081  case   LOCAL_RECV_DIRTY_COUNT:
1082    return "LOCAL_RECV_DIRTY_COUNT";
1083  case   LOCAL_RECV_CLEAN_COUNT:
1084    return "LOCAL_RECV_CLEAN_COUNT";
1085  case   LOCAL_CPU_UTIL:
1086    return "LOCAL_CPU_UTIL";
1087  case   LOCAL_CPU_PERCENT_USER:
1088    return "LOCAL_CPU_PERCENT_USER";
1089  case   LOCAL_CPU_PERCENT_SYSTEM:
1090    return "LOCAL_CPU_PERCENT_SYSTEM";
1091  case   LOCAL_CPU_PERCENT_IOWAIT:
1092    return "LOCAL_CPU_PERCENT_IOWAIT";
1093  case   LOCAL_CPU_PERCENT_IRQ:
1094    return "LOCAL_CPU_PERCENT_IRQ";
1095  case   LOCAL_CPU_PERCENT_SWINTR:
1096    return "LOCAL_CPU_PERCENT_SWINTR";
1097  case   LOCAL_CPU_BIND:
1098    return "LOCAL_CPU_BIND";
1099  case   LOCAL_SD:
1100    return "LOCAL_SD";
1101  case   SD_UNITS:
1102    return "SD_UNITS";
1103  case   LOCAL_CPU_METHOD:
1104    return "LOCAL_CPU_METHOD";
1105  case LOCAL_CPU_COUNT:
1106    return "LOCAL_CPU_COUNT";
1107  case   LOCAL_CPU_PEAK_UTIL:
1108    return "LOCAL_CPU_PEAK_UTIL";
1109  case LOCAL_CPU_PEAK_ID:
1110    return "LOCAL_CPU_PEAK_ID";
1111  case   LOCAL_NODELAY:
1112    return "LOCAL_NODELAY";
1113  case   LOCAL_CORK:
1114    return "LOCAL_CORK";
1115  case   RSS_SIZE_REQ:
1116    return "RSS_SIZE_REQ";
1117  case   RSS_SIZE:
1118    return "RSS_SIZE";
1119  case   RSS_SIZE_END:
1120    return "RSS_SIZE_END";
1121  case   RSR_SIZE_REQ:
1122    return "RSR_SIZE_REQ";
1123  case   RSR_SIZE:
1124    return "RSR_SIZE";
1125  case   RSR_SIZE_END:
1126    return "RSR_SIZE_END";
1127  case   REMOTE_SEND_SIZE:
1128    return "REMOTE_SEND_SIZE";
1129  case   REMOTE_RECV_SIZE:
1130    return "REMOTE_RECV_SIZE";
1131  case   REMOTE_SEND_CALLS:
1132    return "REMOTE_SEND_CALLS";
1133  case   REMOTE_RECV_CALLS:
1134    return "REMOTE_RECV_CALLS";
1135  case   REMOTE_BYTES_PER_RECV:
1136    return "REMOTE_BYTES_PER_RECV";
1137  case   REMOTE_BYTES_PER_SEND:
1138    return "REMOTE_BYTES_PER_SEND";
1139  case   REMOTE_BYTES_SENT:
1140    return "REMOTE_BYTES_SENT";
1141  case   REMOTE_BYTES_RECVD:
1142    return "REMOTE_BYTES_RECVD";
1143  case   REMOTE_BYTES_XFERD:
1144    return "REMOTE_BYTES_XFERD";
1145  case REMOTE_SEND_OFFSET:
1146    return "REMOTE_SEND_OFFSET";
1147  case REMOTE_RECV_OFFSET:
1148    return "REMOTE_RECV_OFFSET";
1149  case REMOTE_RECV_ALIGN:
1150    return "REMOTE_RECV_ALIGN";
1151  case REMOTE_SEND_ALIGN:
1152    return "REMOTE_SEND_ALIGN";
1153  case REMOTE_SEND_WIDTH:
1154    return "REMOTE_SEND_WIDTH";
1155  case REMOTE_RECV_WIDTH:
1156    return "REMOTE_RECV_WIDTH";
1157  case   REMOTE_SEND_DIRTY_COUNT:
1158    return "REMOTE_SEND_DIRTY_COUNT";
1159  case   REMOTE_RECV_DIRTY_COUNT:
1160    return "REMOTE_RECV_DIRTY_COUNT";
1161  case   REMOTE_RECV_CLEAN_COUNT:
1162    return "REMOTE_RECV_CLEAN_COUNT";
1163  case   REMOTE_CPU_UTIL:
1164    return "REMOTE_CPU_UTIL";
1165  case   REMOTE_CPU_PERCENT_USER:
1166    return "REMOTE_CPU_PERCENT_USER";
1167  case   REMOTE_CPU_PERCENT_SYSTEM:
1168    return "REMOTE_CPU_PERCENT_SYSTEM";
1169  case   REMOTE_CPU_PERCENT_IOWAIT:
1170    return "REMOTE_CPU_PERCENT_IOWAIT";
1171  case   REMOTE_CPU_PERCENT_IRQ:
1172    return "REMOTE_CPU_PERCENT_IRQ";
1173  case   REMOTE_CPU_PERCENT_SWINTR:
1174    return "REMOTE_CPU_PERCENT_SWINTR";
1175  case   REMOTE_CPU_BIND:
1176    return "REMOTE_CPU_BIND";
1177  case   REMOTE_SD:
1178    return "REMOTE_SD";
1179  case   REMOTE_CPU_METHOD:
1180    return "REMOTE_CPU_METHOD";
1181  case REMOTE_CPU_COUNT:
1182    return "REMOTE_CPU_COUNT";
1183  case REMOTE_CPU_PEAK_UTIL:
1184    return "REMOTE_CPU_PEAK_UTIL";
1185  case REMOTE_CPU_PEAK_ID:
1186    return "REMOTE_CPU_PEAK_ID";
1187  case   REMOTE_NODELAY:
1188    return "REMOTE_NODELAY";
1189  case   REMOTE_CORK:
1190    return "REMOTE_CORK";
1191  case LOCAL_INTERFACE_SLOT:
1192    return "LOCAL_INTERFACE_SLOT";
1193  case REMOTE_INTERFACE_SLOT:
1194    return "REMOTE_INTERFACE_SLOT";
1195  case REMOTE_INTERFACE_SUBDEVICE:
1196    return "REMOTE_INTERFACE_SUBDEVICE";
1197  case REMOTE_INTERFACE_SUBVENDOR:
1198    return "REMOTE_INTERFACE_SUBVENDOR";
1199  case REMOTE_INTERFACE_DEVICE:
1200    return "REMOTE_INTERFACE_DEVICE";
1201  case REMOTE_INTERFACE_VENDOR:
1202    return "REMOTE_INTERFACE_VENDOR";
1203  case LOCAL_INTERFACE_SUBDEVICE:
1204    return "LOCAL_INTERFACE_SUBDEVICE";
1205  case LOCAL_INTERFACE_SUBVENDOR:
1206    return "LOCAL_INTERFACE_SUBVENDOR";
1207  case LOCAL_INTERFACE_DEVICE:
1208    return "LOCAL_INTERFACE_DEVICE";
1209  case LOCAL_INTERFACE_VENDOR:
1210    return "LOCAL_INTERFACE_VENDOR";
1211  case LOCAL_INTERFACE_NAME:
1212    return "LOCAL_INTERFACE_NAME";
1213  case REMOTE_INTERFACE_NAME:
1214    return "REMOTE_INTERFACE_NAME";
1215  case REMOTE_DRIVER_NAME:
1216    return "REMOTE_DRIVER_NAME";
1217  case REMOTE_DRIVER_VERSION:
1218    return "REMOTE_DRIVER_VERSION";
1219  case REMOTE_DRIVER_FIRMWARE:
1220    return "REMOTE_DRIVER_FIRMWARE";
1221  case REMOTE_DRIVER_BUS:
1222    return "REMOTE_DRIVER_BUS";
1223  case LOCAL_DRIVER_NAME:
1224    return "LOCAL_DRIVER_NAME";
1225  case LOCAL_DRIVER_VERSION:
1226    return "LOCAL_DRIVER_VERSION";
1227  case LOCAL_DRIVER_FIRMWARE:
1228    return "LOCAL_DRIVER_FIRMWARE";
1229  case LOCAL_INTERVAL_USECS:
1230    return "LOCAL_INTERVAL_USECS";
1231  case LOCAL_INTERVAL_BURST:
1232    return "LOCAL_INTERVAL_BURST";
1233  case REMOTE_INTERVAL_USECS:
1234    return "REMOTE_INTERVAL_USECS";
1235  case REMOTE_INTERVAL_BURST:
1236    return "REMOTE_INTERVAL_BURST";
1237  case LOCAL_SECURITY_TYPE_ID:
1238    return "LOCAL_SECURITY_TYPE_ID";
1239  case LOCAL_SECURITY_ENABLED_NUM:
1240    return "LOCAL_SECURITY_ENABLED_NUM";
1241  case LOCAL_SECURITY_TYPE:
1242    return "LOCAL_SECURITY_TYPE";
1243  case LOCAL_SECURITY_ENABLED:
1244    return "LOCAL_SECURITY_ENABLED";
1245  case LOCAL_SECURITY_SPECIFIC:
1246    return "LOCAL_SECURITY_SPECIFIC";
1247  case REMOTE_SECURITY_TYPE_ID:
1248    return "REMOTE_SECURITY_TYPE_ID";
1249  case REMOTE_SECURITY_ENABLED_NUM:
1250    return "REMOTE_SECURITY_ENABLED_NUM";
1251  case REMOTE_SECURITY_TYPE:
1252    return "REMOTE_SECURITY_TYPE";
1253  case REMOTE_SECURITY_ENABLED:
1254    return "REMOTE_SECURITY_ENABLED";
1255  case REMOTE_SECURITY_SPECIFIC:
1256    return "REMOTE_SECURITY_SPECIFIC";
1257  case LOCAL_DRIVER_BUS:
1258    return "LOCAL_DRIVER_BUS";
1259  case REMOTE_SYSNAME:
1260    return "REMOTE_SYSNAME";
1261  case REMOTE_MACHINE:
1262    return "REMOTE_MACHINE";
1263  case REMOTE_VERSION:
1264    return "REMOTE_VERSION";
1265  case REMOTE_RELEASE:
1266    return "REMOTE_RELEASE";
1267  case LOCAL_SYSNAME:
1268    return "LOCAL_SYSNAME";
1269  case LOCAL_MACHINE:
1270    return "LOCAL_MACHINE";
1271  case LOCAL_VERSION:
1272    return "LOCAL_VERSION";
1273  case LOCAL_RELEASE:
1274    return "LOCAL_RELEASE";
1275  case REMOTE_CPU_MODEL:
1276    return "REMOTE_CPU_MODEL";
1277  case REMOTE_CPU_FREQUENCY:
1278    return "REMOTE_CPU_FREQUENCY";
1279  case REMOTE_SYSTEM_MODEL:
1280    return "REMOTE_SYSTEM_MODEL";
1281  case LOCAL_CPU_MODEL:
1282    return "LOCAL_CPU_MODEL";
1283  case LOCAL_CPU_FREQUENCY:
1284    return "LOCAL_CPU_FREQUENCY";
1285  case LOCAL_SYSTEM_MODEL:
1286    return "LOCAL_SYSTEM_MODEL";
1287  case MIN_LATENCY:
1288    return "MIN_LATENCY";
1289  case MAX_LATENCY:
1290    return "MAX_LATENCY";
1291  case P50_LATENCY:
1292    return "P50_LATENCY";
1293  case P90_LATENCY:
1294    return "P90_LATENCY";
1295  case P99_LATENCY:
1296    return "P99_LATENCY";
1297  case MEAN_LATENCY:
1298    return "MEAN_LATENCY";
1299  case STDDEV_LATENCY:
1300    return "STDDEV_LATENCY";
1301  case LOCAL_SOCKET_PRIO:
1302    return "LOCAL_SOCKET_PRIO";
1303  case REMOTE_SOCKET_PRIO:
1304    return "REMOTE_SOCKET_PRIO";
1305  case LOCAL_SOCKET_TOS:
1306    return "LOCAL_SOCKET_TOS";
1307  case REMOTE_SOCKET_TOS:
1308    return "REMOTE_SOCKET_TOS";
1309  case LOCAL_CONG_CONTROL:
1310    return "LOCAL_CONG_CONTROL";
1311  case REMOTE_CONG_CONTROL:
1312    return "REMOTE_CONG_CONTROL";
1313  case LOCAL_FILL_FILE:
1314    return "LOCAL_FILL_FILE";
1315  case REMOTE_FILL_FILE:
1316    return "REMOTE_FILL_FILE";
1317  case OUTPUT_END:
1318    return "OUTPUT_END";
1319  default:
1320    return "!UNKNOWN OUTPUT SELECTOR!";
1321  }
1322}
1323
1324void
1325print_netperf_output_entry(FILE *where, enum netperf_output_name what)
1326{
1327}
1328
1329void print_omni_init_list();
1330
1331void
1332dump_netperf_output_list(FILE *where) {
1333
1334  int i,j;
1335
1336  for (i = 0; i < NETPERF_MAX_BLOCKS; i++) {
1337    fprintf(where,"Output Block %d\n",i + 1);
1338    for (j = 0; j < NETPERF_OUTPUT_MAX; j++) {
1339      fprintf(where,"%s ",netperf_output_enum_to_str(output_list[i][j]));
1340    }
1341    fprintf(where,"\n");
1342  }
1343  fflush(where);
1344}
1345
1346void
1347dump_netperf_output_choices(FILE *where, int csv) {
1348  int i;
1349
1350  print_omni_init_list();
1351
1352  for (i = OUTPUT_NONE; i < NETPERF_OUTPUT_MAX; i++){
1353    if (OUTPUT_NONE != i) {
1354      fprintf(where,"%c",(csv) ? ',' : '\n');
1355    }
1356    fprintf(where,
1357	    "%s",
1358	    netperf_output_enum_to_str(netperf_output_source[i].output_name));
1359  }
1360  fprintf(where,"\n");
1361  fflush(where);
1362}
1363
1364void
1365dump_netperf_output_source(FILE *where)
1366{
1367  int i;
1368
1369  /* belts and suspenders everyone... */
1370  for (i = OUTPUT_NONE; i < NETPERF_OUTPUT_MAX; i++) {
1371    fprintf(where,
1372	    "Output Name: %s\n"
1373	    "\tmax_line_len %d tot_line_len %d display_value %p\n"
1374	    "\tline[0]: |%s|\n"
1375	    "\tline[1]: |%s|\n"
1376	    "\tline[2]: |%s|\n"
1377	    "\tline[3]: |%s|\n"
1378	    "\tformat: |%s|\n",
1379	    netperf_output_enum_to_str(netperf_output_source[i].output_name),
1380	    netperf_output_source[i].max_line_len,
1381	    netperf_output_source[i].tot_line_len,
1382	    netperf_output_source[i].display_value,
1383	    (netperf_output_source[i].line[0] == NULL) ? "" :
1384	    netperf_output_source[i].line[0],
1385	    (netperf_output_source[i].line[1] == NULL) ? "" :
1386	    netperf_output_source[i].line[1],
1387	    (netperf_output_source[i].line[2] == NULL) ? "" :
1388	    netperf_output_source[i].line[2],
1389	    (netperf_output_source[i].line[3] == NULL) ? "" :
1390	    netperf_output_source[i].line[3],
1391	    (netperf_output_source[i].format == NULL) ? "" :
1392	    netperf_output_source[i].format);
1393  }
1394  fflush(where);
1395}
1396
1397#define MY_MAX(a,b) ((a > b) ? a : b)
1398
1399#define NETPERF_LINE_MAX(x) \
1400    MY_MAX(MY_MAX(MY_MAX(strlen(netperf_output_source[x].line[0]),\
1401		         strlen(netperf_output_source[x].line[1])),\
1402	          strlen(netperf_output_source[x].line[2])),\
1403	   strlen(netperf_output_source[x].line[3]))
1404
1405#define NETPERF_LINE_TOT(x) \
1406    strlen(netperf_output_source[x].line[0]) +\
1407    strlen(netperf_output_source[x].line[1]) +\
1408    strlen(netperf_output_source[x].line[2]) +\
1409    strlen(netperf_output_source[x].line[3]) + 4
1410
1411enum netperf_output_name
1412match_string_to_output_mnenomic(char *candidate) {
1413
1414  enum netperf_output_name name;
1415  for (name = OUTPUT_NONE; name < NETPERF_OUTPUT_MAX; name++) {
1416    if(!strcasecmp(candidate,netperf_output_enum_to_str(name)))
1417      return name;
1418  }
1419  return NETPERF_OUTPUT_UNKNOWN;
1420}
1421
1422enum netperf_output_name
1423match_string_to_output(char *candidate)
1424{
1425  char *h1,*temp;
1426  enum netperf_output_name name;
1427  int k,len;
1428
1429  /* at some point we may need/want to worry about leading and
1430     trailing spaces, but for now we will leave that onus on the
1431     user. */
1432
1433  for (name = OUTPUT_NONE; name < NETPERF_OUTPUT_MAX; name++) {
1434    /* try for a match based on the nmemonic/enum */
1435    if (!strcasecmp(candidate,netperf_output_enum_to_str(name)))
1436      return name;
1437
1438    /* try for a match on the actual header text */
1439    temp = malloc(NETPERF_LINE_TOT(name));
1440    h1 = temp;
1441    if (h1 != NULL) {
1442      for (k = 0; ((k < 4) &&
1443		   (NULL != netperf_output_source[name].line[k]) &&
1444		   (strcmp("",netperf_output_source[name].line[k]))); k++) {
1445	len = sprintf(h1,
1446		      "%s",
1447		      netperf_output_source[name].line[k]);
1448	*(h1 + len) = ' ';
1449	/* now move to the next starting column. for csv we aren't worried
1450	   about alignment between the header and the value lines */
1451	h1 += len + 1;
1452      }
1453      /* this time we want null termination please */
1454      *(h1 - 1) = 0;
1455      if (!strcasecmp(candidate,temp)) {
1456	free(temp);
1457	return name;
1458      }
1459      else
1460	free(temp);
1461    }
1462  }
1463  /* if we get here it means there was no match */
1464  return OUTPUT_NONE;
1465}
1466
1467
1468void
1469set_output_list_all() {
1470
1471  int i, j;  /* line, column */
1472  enum netperf_output_name k;
1473
1474  /* Line One SOCKET_TYPE to RESPONSE_SIZE */
1475  i = 0;
1476  j = 0;
1477  for (k = SOCKET_TYPE; k <= RESPONSE_SIZE; k++) {
1478    output_list[i][j++] = k;
1479    desired_output_groups |= netperf_output_source[k].output_group;
1480  }
1481
1482  /* Line Two LOCAL_CPU_UTIL to TRANSPORT_MSS */
1483  i = 1;
1484  j = 0;
1485  for (k = LOCAL_CPU_UTIL; k <= TRANSPORT_MSS; k++) {
1486    output_list[i][j++] = k;
1487    desired_output_groups |= netperf_output_source[k].output_group;
1488  }
1489
1490  /* Line Three LOCAL_SEND_THROUGHPUT throught REMOTE_CORK */
1491  i = 2;
1492  j = 0;
1493  for (k = LOCAL_SEND_THROUGHPUT; k <= REMOTE_CORK; k++) {
1494    output_list[i][j++] = k;
1495    desired_output_groups |= netperf_output_source[k].output_group;
1496  }
1497
1498  /* Line Four LOCAL_SYSNAME through COMMAND_LINE */
1499  i = 3;
1500  j = 0;
1501  for (k = LOCAL_SYSNAME; k <= COMMAND_LINE; k++) {
1502    output_list[i][j++] = k;
1503    desired_output_groups |= netperf_output_source[k].output_group;
1504  }
1505
1506}
1507
1508void
1509parse_output_selection_file(char *selection_file) {
1510  FILE *selections;
1511  char name[81]; /* best be more than enough */
1512  int namepos;
1513  int c;
1514  int j;
1515  int line,column;
1516
1517  selections = fopen(selection_file,"r");
1518  if (!selections) {
1519    fprintf(where,
1520	    "Could not open output selection file '%s' errno %d\n",
1521	    selection_file,
1522	    errno);
1523    fflush(where);
1524    exit(-1);
1525  }
1526
1527  line = 0;
1528  column = 1;
1529  namepos = 0;
1530  name[0] = 0;
1531  name[80] = 0;
1532  j = 0;
1533  while (((c = fgetc(selections)) != EOF) && (line < 4)) {
1534    if (namepos == 80) {
1535      /* too long */
1536
1537      fprintf(where,
1538	      "Output selection starting column %d on line %d is too long\n",
1539	      line + 1,
1540	      column);
1541      fflush(where);
1542      exit(-1);
1543    }
1544    if (c == ',') {
1545      /* time to check for a match, but only if we won't overflow the
1546	 current row of the array  */
1547      if (j == NETPERF_OUTPUT_MAX) {
1548	fprintf(where,"Too many output selectors on line %d\n",line);
1549	fflush(where);
1550	exit(-1);
1551      }
1552      name[namepos] = 0;
1553      output_list[line][j++] = match_string_to_output(name);
1554      namepos = 0;
1555    }
1556    else if (c == '\n') {
1557      /* move to the next line after checking for a match */
1558      name[namepos] = 0;
1559      output_list[line++][j++] = match_string_to_output(name);
1560      namepos = 0;
1561      j = 0;
1562    }
1563    else if (isprint(c)) {
1564      name[namepos++] = (char)c;
1565    }
1566    column++;
1567  }
1568
1569  /* ok, do we need/want to do anything here? at present we will
1570     silently ignore the rest of the file if we exit the loop on line
1571     count */
1572  if ((c == EOF) && (namepos > 0)) {
1573    name[namepos] = 0;
1574    output_list[line][j] =   match_string_to_output(name);
1575  }
1576
1577}
1578
1579void
1580parse_output_selection_line(int line, char *list) {
1581
1582  char *token;
1583  int j;
1584  enum netperf_output_name name;
1585
1586  /* belt and suspenders */
1587  if (line < 0) {
1588    fprintf(where,
1589	    "parse_output_selection_line called with negative line number %d\n",line);
1590    fflush(where);
1591    exit(-1);
1592  }
1593
1594  /* silently ignore extra lines and only warn if debug is set */
1595  if (line >= NETPERF_MAX_BLOCKS) {
1596    if (debug) {
1597      fprintf(where,
1598	      "There can be no more than %d output selection lines."
1599	      " Ignoring output selection line %d |%s|\n",
1600	      NETPERF_MAX_BLOCKS,
1601	      line + 1,
1602	      list);
1603      fflush(where);
1604    }
1605    return;
1606  }
1607
1608
1609  j=0;
1610  token = strtok(list," ,");
1611  while ((token) && (j < NETPERF_OUTPUT_MAX)) {
1612
1613    name = match_string_to_output_mnenomic(token);
1614
1615    if ((name == NETPERF_OUTPUT_UNKNOWN) && (debug)) {
1616      fprintf(where,"Ignoring unknown output selector %d |%s| on line %d\n",
1617	      j + 1,
1618	      token,
1619	      line +1);
1620      fflush(where);
1621    }
1622    else {
1623      output_list[line][j] = name;
1624      desired_output_groups |= netperf_output_source[name].output_group;
1625      j++;
1626    }
1627
1628    token = strtok(NULL," ,");
1629  }
1630  if ((token) && (debug)) {
1631    fprintf(where,
1632	    "There can be no more than %d output selectors per line. "
1633	    "Ignoring remaining selectors on line %d\n",
1634	    NETPERF_OUTPUT_MAX,line +1);
1635    fflush(where);
1636  }
1637}
1638
1639void
1640parse_output_selection_direct(char *output_selection) {
1641
1642  char *source,*line,*remainder,*temp;
1643  char *f1, *f2, *f3;
1644  int i,len,done;
1645
1646  len = strlen(output_selection);
1647
1648  source = strdup(output_selection);
1649  line = (char *) malloc(len+1);
1650  remainder = (char *) malloc(len+1);
1651
1652  if ((NULL == source) ||
1653      (NULL == line) ||
1654      (NULL == remainder)) {
1655    fprintf(where,"Unable to malloc memory for output selection parsing\n");
1656    fflush(where);
1657    exit(-1);
1658  }
1659
1660  f1 = source;
1661  f2 = line;
1662  f3 = remainder;
1663
1664  i = 0;
1665  done = 0;
1666  do {
1667    break_args_explicit_sep(source,';',line,remainder);
1668    if (line[0]) {
1669      parse_output_selection_line(i,line);
1670    }
1671    if (remainder[0]) {
1672      temp = source;
1673      source = remainder;
1674      remainder = temp;
1675      i++;
1676      /*
1677      if (i == NETPERF_MAX_BLOCKS) {
1678	fprintf(where,
1679		"Too many output blocks requested, maximum is %d\n",
1680		NETPERF_MAX_BLOCKS);
1681	fflush(where);
1682	exit(-1);
1683      }
1684      */
1685      continue;
1686    }
1687    else {
1688      done = 1;
1689    }
1690  } while (!done);
1691
1692  free(f1);
1693  free(f2);
1694  free(f3);
1695
1696}
1697
1698/* building blocks for output selection */
1699#define NETPERF_TPUT "ELAPSED_TIME,THROUGHPUT,THROUGHPUT_UNITS"
1700#define NETPERF_OUTPUT_STREAM "LSS_SIZE_END,RSR_SIZE_END,LOCAL_SEND_SIZE"
1701#define NETPERF_OUTPUT_MAERTS "RSS_SIZE_END,LSR_SIZE_END,REMOTE_SEND_SIZE"
1702#define NETPERF_CPU "LOCAL_CPU_UTIL,LOCAL_CPU_PERCENT_USER,LOCAL_CPU_PERCENT_SYSTEM,LOCAL_CPU_PERCENT_IOWAIT,LOCAL_CPU_PERCENT_IRQ,LOCAL_CPU_PERCENT_SWINTR,LOCAL_CPU_METHOD,REMOTE_CPU_UTIL,REMOTE_CPU_PERCENT_USER,REMOTE_CPU_PERCENT_SYSTEM,REMOTE_CPU_PERCENT_IOWAIT,REMOTE_CPU_PERCENT_IRQ,REMOTE_CPU_PERCENT_SWINTR,REMOTE_CPU_METHOD,LOCAL_SD,REMOTE_SD,SD_UNITS"
1703#define NETPERF_RR "LSS_SIZE_END,LSR_SIZE_END,RSR_SIZE_END,RSS_SIZE_END,REQUEST_SIZE,RESPONSE_SIZE"
1704
1705void
1706set_output_list_by_test() {
1707
1708  char *stream_no_cpu = NETPERF_OUTPUT_STREAM "," NETPERF_TPUT;
1709  char *stream_cpu = NETPERF_OUTPUT_STREAM "," NETPERF_TPUT "," NETPERF_CPU;
1710  char *maerts_no_cpu = NETPERF_OUTPUT_MAERTS "," NETPERF_TPUT;
1711  char *maerts_cpu =  NETPERF_OUTPUT_MAERTS "," NETPERF_TPUT "," NETPERF_CPU;
1712  char *rr_no_cpu = NETPERF_RR "," NETPERF_TPUT;
1713  char *rr_cpu = NETPERF_RR "," NETPERF_TPUT "," NETPERF_CPU;
1714
1715  if (debug) {
1716    fprintf(where,"%s setting the output list by test\n",
1717	    __FUNCTION__);
1718    fflush(where);
1719  }
1720
1721  if (NETPERF_XMIT_ONLY(direction)) {
1722    if (!(local_cpu_usage || remote_cpu_usage))
1723      parse_output_selection_direct(stream_no_cpu);
1724    else
1725      parse_output_selection_direct(stream_cpu);
1726  }
1727  else if (NETPERF_RECV_ONLY(direction)) {
1728    if (!(local_cpu_usage || remote_cpu_usage))
1729      parse_output_selection_direct(maerts_no_cpu);
1730    else
1731      parse_output_selection_direct(maerts_cpu);
1732  }
1733  else if (NETPERF_CC(direction)) {
1734    if (!(local_cpu_usage || remote_cpu_usage))
1735      parse_output_selection_direct(rr_no_cpu);
1736    else
1737      parse_output_selection_direct(rr_cpu);
1738  }
1739  else if (NETPERF_IS_RR(direction)) {
1740    if (!(local_cpu_usage || remote_cpu_usage))
1741      parse_output_selection_direct(rr_no_cpu);
1742    else
1743      parse_output_selection_direct(rr_cpu);
1744  }
1745  else {
1746    /* no idea */
1747    if (debug) {
1748      fprintf(where,"Cannot determine default test output, using mins\n");
1749      fflush(where);
1750    }
1751    parse_output_selection_direct(NETPERF_TPUT "," NETPERF_CPU);
1752  }
1753}
1754
1755void
1756parse_output_selection(char *output_selection) {
1757
1758  if (debug) {
1759    fprintf(where,"%s is parsing the output selection '%s'\n",
1760	    __FUNCTION__,
1761	    output_selection);
1762    fflush(where);
1763  }
1764
1765  /* is it the magic keyword? */
1766  if (strcasecmp(output_selection,"all") == 0) {
1767    set_output_list_all();
1768  }
1769  /* do not forget the case when the output_selection is a single
1770     mnemonic without any separators... */
1771  else if (strchr(output_selection,',') ||
1772	   strchr(output_selection,';') ||
1773	   (match_string_to_output_mnenomic(output_selection) !=
1774	    NETPERF_OUTPUT_UNKNOWN)) {
1775    parse_output_selection_direct(output_selection);
1776  }
1777  else {
1778    parse_output_selection_file(output_selection);
1779  }
1780  if (debug > 2) {
1781    dump_netperf_output_list(stderr);
1782  }
1783  return;
1784}
1785
1786static void
1787set_output_elt(enum netperf_output_name name,
1788	       char *line0, char *line1, char *line2, char *line3,
1789	       char *format,
1790	       void *value,
1791	       unsigned int out_default,
1792	       unsigned int group,
1793	       enum netperf_output_type type) {
1794
1795  netperf_output_source[name].output_name = name;
1796  netperf_output_source[name].line[0] = line0;
1797  netperf_output_source[name].line[1] = line1;
1798  netperf_output_source[name].line[2] = line2;
1799  netperf_output_source[name].line[3] = line3;
1800  netperf_output_source[name].format = format;
1801  netperf_output_source[name].display_value = value;
1802  netperf_output_source[name].output_default = out_default;
1803  netperf_output_source[name].output_group = group;
1804  netperf_output_source[name].max_line_len = NETPERF_LINE_MAX(name);
1805  netperf_output_source[name].tot_line_len = NETPERF_LINE_TOT(name);
1806  netperf_output_source[name].output_type = type;
1807}
1808
1809void
1810print_omni_init_list() {
1811
1812  int i;
1813
1814  if (debug) {
1815    fprintf(where,"%s called\n",
1816	    __FUNCTION__);
1817  }
1818
1819  /* belts and suspenders everyone... */
1820  for (i = NETPERF_OUTPUT_UNKNOWN; i < NETPERF_OUTPUT_MAX; i++) {
1821    netperf_output_source[i].output_name = i;
1822    netperf_output_source[i].max_line_len = 0;
1823    netperf_output_source[i].tot_line_len = 0;
1824    netperf_output_source[i].line[0] = "";
1825    netperf_output_source[i].line[1] = "";
1826    netperf_output_source[i].line[2] = "";
1827    netperf_output_source[i].line[3] = "";
1828    netperf_output_source[i].format = "";
1829    netperf_output_source[i].display_value = NULL;
1830    netperf_output_source[i].output_default = 1;
1831    netperf_output_source[i].output_group = 0;
1832    netperf_output_source[i].output_type = NETPERF_TYPE_UNKNOWN;
1833  }
1834
1835  set_output_elt(OUTPUT_NONE, " ", "", "", "", "%s", &" ",1, 0,
1836		 NETPERF_TYPE_CHAR);
1837
1838  set_output_elt(COMMAND_LINE, "Command","Line","","","\"%s\"",
1839		 command_line,1, 0, NETPERF_TYPE_CHAR);
1840
1841  set_output_elt(UUID, "Test", "UUID", "", "", "%s", test_uuid, 1, 0,
1842		 NETPERF_TYPE_CHAR);
1843
1844  set_output_elt(RESULT_BRAND, "Result", "Tag", "", "", "\"%s\"",
1845		 result_brand, 1, 0, NETPERF_TYPE_CHAR);
1846
1847  set_output_elt(SOCKET_TYPE, "Socket", "Type", "", "", "%s",
1848		 socket_type_str, 1, 0, NETPERF_TYPE_CHAR);
1849
1850  set_output_elt(DIRECTION, "Direction", "", "", "", "%s",
1851		 direction_str, 1, 0, NETPERF_TYPE_CHAR);
1852
1853  set_output_elt(PROTOCOL, "Protocol", "", "", "", "%s",
1854		 protocol_str, 1, 0, NETPERF_TYPE_CHAR);
1855
1856  set_output_elt(ELAPSED_TIME, "Elapsed", "Time", "(sec)", "", "%.2f",
1857		 &elapsed_time_double, 1, 0, NETPERF_TYPE_DOUBLE);
1858
1859  set_output_elt(SOURCE_PORT, "Source", "Port", "", "", "%s",
1860		 local_data_port, 1, 0, NETPERF_TYPE_CHAR);
1861
1862  set_output_elt(SOURCE_ADDR, "Source", "Address", "", "", "%s",
1863		 local_data_address, 1, 0, NETPERF_TYPE_CHAR);
1864
1865  set_output_elt(SOURCE_FAMILY, "Source", "Family", "", "", "%d",
1866		 &local_data_family, 1, 0, NETPERF_TYPE_INT32);
1867
1868  set_output_elt(DEST_PORT, "Destination", "Port", "", "", "%s",
1869		 remote_data_port, 1, 0, NETPERF_TYPE_CHAR);
1870
1871  set_output_elt(DEST_ADDR, "Destination", "Address", "", "", "%s",
1872		 remote_data_address, 1, 0, NETPERF_TYPE_CHAR);
1873
1874  set_output_elt(DEST_FAMILY, "Destination", "Family", "", "", "%d",
1875		 &remote_data_family, 1, 0, NETPERF_TYPE_INT32);
1876
1877  set_output_elt(THROUGHPUT, "Throughput", "", "", "", "%.2f",
1878		 &thruput, 1, 0, NETPERF_TYPE_DOUBLE);
1879
1880  set_output_elt(LOCAL_SEND_THROUGHPUT, "Local", "Send", "Throughput", "",
1881		 "%.2f", &local_send_thruput, 1, 0, NETPERF_TYPE_DOUBLE);
1882
1883  set_output_elt(LOCAL_RECV_THROUGHPUT, "Local", "Recv", "Throughput", "",
1884		 "%.2f", &local_recv_thruput, 1, 0, NETPERF_TYPE_DOUBLE);
1885
1886  set_output_elt(REMOTE_SEND_THROUGHPUT, "Remote", "Send", "Throughput", "",
1887		 "%.2f", &remote_send_thruput, 1, 0, NETPERF_TYPE_DOUBLE);
1888
1889  set_output_elt(REMOTE_RECV_THROUGHPUT, "Remote", "Recv", "Throughput", "",
1890		 "%.2f", &remote_recv_thruput, 1, 0, NETPERF_TYPE_DOUBLE);
1891
1892  set_output_elt(THROUGHPUT_UNITS, "Throughput", "Units", "", "", "%s/s",
1893		 thruput_format_str, 1, 0, NETPERF_TYPE_CHAR);
1894
1895  set_output_elt(CONFIDENCE_LEVEL, "Confidence", "Level", "Percent", "", "%d",
1896		 &confidence_level, 1, 0, NETPERF_TYPE_INT32);
1897
1898  set_output_elt(CONFIDENCE_INTERVAL, "Confidence", "Width", "Target", "",
1899		 "%f", &interval_pct, 1, 0, NETPERF_TYPE_DOUBLE);
1900
1901  set_output_elt(CONFIDENCE_ITERATION, "Confidence", "Iterations", "Run", "",
1902		 "%d", &confidence_iteration, 1, 0, NETPERF_TYPE_INT32);
1903
1904  set_output_elt(THROUGHPUT_CONFID, "Throughput", "Confidence", "Width (%)",
1905		 "", "%.3f", &result_confid_pct, 1, 0, NETPERF_TYPE_DOUBLE);
1906
1907  set_output_elt(LOCAL_CPU_CONFID, "Local", "CPU", "Confidence", "Width (%)",
1908		 "%.3f", &loc_cpu_confid_pct, 1, 0, NETPERF_TYPE_DOUBLE);
1909
1910  set_output_elt(REMOTE_CPU_CONFID, "Remote", "CPU", "Confidence", "Width (%)",
1911		 "%.3f", &rem_cpu_confid_pct, 1, 0, NETPERF_TYPE_DOUBLE);
1912
1913  set_output_elt(RT_LATENCY, "Round", "Trip", "Latency", "usec/tran", "%.3f",
1914		 &rtt_latency, 1, 0, NETPERF_TYPE_DOUBLE);
1915
1916  set_output_elt(TRANSACTION_RATE, "Transaction", "Rate", "Tran/s", "", "%.3f",
1917		 &transaction_rate, 1, 0, NETPERF_TYPE_DOUBLE);
1918
1919  set_output_elt(TRANSPORT_MSS, "Transport", "MSS", "bytes", "", "%d",
1920		 &transport_mss, 1, 0, NETPERF_TYPE_INT32);
1921
1922  set_output_elt(LOCAL_TRANSPORT_RETRANS, "Local", "Transport",
1923		 "Retransmissions", "", "%d", &local_transport_retrans, 1, 0,
1924		 NETPERF_TYPE_INT32);
1925
1926  set_output_elt(REMOTE_TRANSPORT_RETRANS, "Remote", "Transport",
1927		 "Retransmissions", "", "%d", &remote_transport_retrans, 1, 0,
1928		 NETPERF_TYPE_INT32);
1929
1930  set_output_elt(REQUEST_SIZE, "Request", "Size", "Bytes", "", "%d",
1931		 &req_size, 1, 0, NETPERF_TYPE_INT32);
1932
1933  set_output_elt(RESPONSE_SIZE, "Response", "Size", "Bytes", "", "%d",
1934		 &rsp_size, 1, 0, NETPERF_TYPE_INT32);
1935
1936  set_output_elt(BURST_SIZE, "Initial", "Burst", "Requests", "", "%d",
1937		 &first_burst_size, 1, 0, NETPERF_TYPE_INT32);
1938
1939  set_output_elt(LSS_SIZE_REQ, "Local", "Send Socket", "Size", "Requested",
1940		 "%d", &lss_size_req, 1, 0, NETPERF_TYPE_INT32);
1941
1942  set_output_elt(LSS_SIZE, "Local", "Send Socket", "Size", "Initial", "%d",
1943		 &lss_size, 1, 0, NETPERF_TYPE_INT32);
1944
1945  set_output_elt(LSS_SIZE_END, "Local", "Send Socket", "Size", "Final", "%d",
1946		 &lss_size_end, 1, 0, NETPERF_TYPE_INT32);
1947
1948  set_output_elt(LSR_SIZE_REQ, "Local", "Recv Socket", "Size", "Requested",
1949		 "%d", &lsr_size_req, 1, 0, NETPERF_TYPE_INT32);
1950
1951  set_output_elt(LSR_SIZE, "Local", "Recv Socket", "Size", "Initial", "%d",
1952		 &lsr_size, 1, 0, NETPERF_TYPE_INT32);
1953
1954  set_output_elt(LSR_SIZE_END, "Local", "Recv Socket", "Size", "Final", "%d",
1955		 &lsr_size_end, 1, 0, NETPERF_TYPE_INT32);
1956
1957  set_output_elt(LOCAL_SEND_SIZE, "Local", "Send", "Size", "", "%d",
1958		 &send_size, 1, 0, NETPERF_TYPE_INT32);
1959
1960  set_output_elt(LOCAL_RECV_SIZE, "Local", "Recv", "Size", "", "%d",
1961		 &recv_size, 1, 0, NETPERF_TYPE_INT32);
1962
1963  set_output_elt(LOCAL_SEND_CALLS, "Local", "Send", "Calls", "", "%"PRIu64,
1964		 &local_send_calls, 1, 0, NETPERF_TYPE_UINT64);
1965
1966  set_output_elt(LOCAL_RECV_CALLS, "Local", "Recv", "Calls", "", "%"PRIu64,
1967		 &local_receive_calls, 1, 0, NETPERF_TYPE_UINT64);
1968
1969  set_output_elt(LOCAL_BYTES_PER_RECV, "Local", "Bytes", "Per", "Recv", "%.2f",
1970		 &bytes_per_recv, 1, 0, NETPERF_TYPE_DOUBLE);
1971
1972  set_output_elt(LOCAL_BYTES_PER_SEND, "Local", "Bytes", "Per", "Send", "%.2f",
1973		 &bytes_per_send, 1, 0, NETPERF_TYPE_DOUBLE);
1974
1975  set_output_elt(LOCAL_BYTES_RECVD, "Local", "Bytes", "Received", "", "%"PRIu64,
1976		 &bytes_received, 1, 0, NETPERF_TYPE_UINT64);
1977
1978  set_output_elt(LOCAL_BYTES_SENT, "Local", "Bytes", "Sent", "", "%"PRIu64,
1979		 &bytes_sent, 1, 0, NETPERF_TYPE_UINT64);
1980
1981  set_output_elt(LOCAL_BYTES_XFERD, "Local", "Bytes", "Xferred", "", "%.0f",
1982		 &bytes_xferd, 1, 0, NETPERF_TYPE_DOUBLE);
1983
1984  set_output_elt(LOCAL_SEND_WIDTH, "Local", "Send", "Width", "", "%d",
1985		 &send_width, 1, 0, NETPERF_TYPE_INT32);
1986
1987  set_output_elt(LOCAL_RECV_WIDTH, "Local", "Recv", "Width", "", "%d",
1988		 &recv_width, 1, 0, NETPERF_TYPE_INT32);
1989
1990  set_output_elt(LOCAL_SEND_OFFSET, "Local", "Send", "Offset", "", "%d",
1991		 &local_send_offset, 1, 0, NETPERF_TYPE_INT32);
1992
1993  set_output_elt(LOCAL_RECV_OFFSET, "Local", "Recv", "Offset", "", "%d",
1994		 &local_recv_offset, 1, 0, NETPERF_TYPE_INT32);
1995
1996  set_output_elt(LOCAL_RECV_ALIGN, "Local", "Recv", "Alignment", "", "%d",
1997		 &local_recv_align, 1, 0, NETPERF_TYPE_INT32);
1998
1999  set_output_elt(LOCAL_SEND_ALIGN, "Local", "Send", "Alignment", "", "%d",
2000		 &local_send_align, 1, 0, NETPERF_TYPE_INT32);
2001
2002  set_output_elt(LOCAL_SEND_DIRTY_COUNT, "Local", "Send", "Dirty", "Count",
2003		 "%d", &loc_dirty_count, 1, 0, NETPERF_TYPE_INT32);
2004
2005  set_output_elt(LOCAL_RECV_DIRTY_COUNT, "Local", "Recv", "Dirty", "Count",
2006		 "%d", &loc_dirty_count, 1, 0, NETPERF_TYPE_INT32);
2007
2008  set_output_elt(LOCAL_RECV_CLEAN_COUNT, "Local", "Recv", "Clean", "Count",
2009		 "%d", &loc_clean_count, 1, 0, NETPERF_TYPE_INT32);
2010
2011  set_output_elt(LOCAL_CPU_UTIL, "Local", "CPU", "Util", "%", "%.2f",
2012		 &local_cpu_utilization, 1, 0, NETPERF_TYPE_FLOAT);
2013
2014  set_output_elt(LOCAL_CPU_PERCENT_USER, "Local", "CPU", "User", "%", "%.2f",
2015		 &lib_local_cpu_stats.cpu_user, 1, 0, NETPERF_TYPE_FLOAT);
2016
2017  set_output_elt(LOCAL_CPU_PERCENT_SYSTEM,
2018                 "Local", "CPU", "System", "%", "%.2f",
2019		 &lib_local_cpu_stats.cpu_system, 1, 0, NETPERF_TYPE_FLOAT);
2020
2021  set_output_elt(LOCAL_CPU_PERCENT_IOWAIT,
2022                 "Local", "CPU", "I/O", "%", "%.2f",
2023		 &lib_local_cpu_stats.cpu_iowait, 1, 0, NETPERF_TYPE_FLOAT);
2024
2025  set_output_elt(LOCAL_CPU_PERCENT_IRQ,
2026                 "Local", "CPU", "IRQ", "%", "%.2f",
2027		 &lib_local_cpu_stats.cpu_irq, 1, 0, NETPERF_TYPE_FLOAT);
2028
2029  set_output_elt(LOCAL_CPU_PERCENT_SWINTR,
2030                 "Local", "CPU", "swintr", "%", "%.2f",
2031		 &lib_local_cpu_stats.cpu_swintr, 1, 0, NETPERF_TYPE_FLOAT);
2032
2033  set_output_elt(LOCAL_CPU_PEAK_UTIL, "Local", "Peak", "Per CPU", "Util %",
2034		 "%.2f", &lib_local_cpu_stats.peak_cpu_util, 1, 0,
2035                 NETPERF_TYPE_FLOAT);
2036
2037  set_output_elt(LOCAL_CPU_PEAK_ID, "Local", "Peak", "Per CPU", "ID", "%d",
2038		 &lib_local_cpu_stats.peak_cpu_id, 1, 0, NETPERF_TYPE_INT32);
2039
2040  set_output_elt(LOCAL_CPU_BIND, "Local", "CPU", "Bind", "", "%d",
2041		 &local_proc_affinity, 1, 0, NETPERF_TYPE_INT32);
2042
2043  set_output_elt(LOCAL_SD, "Local", "Service", "Demand", "", "%.3f",
2044		 &local_service_demand_double, 1, 0, NETPERF_TYPE_DOUBLE);
2045
2046  set_output_elt(SD_UNITS, "Service", "Demand", "Units", "", "%s",
2047		 sd_str, 1, 0, NETPERF_TYPE_CHAR);
2048
2049  set_output_elt(LOCAL_CPU_METHOD, "Local", "CPU", "Util", "Method", "%c",
2050		 &local_cpu_method, 1, 0, NETPERF_TYPE_INT32);
2051
2052  set_output_elt(LOCAL_CPU_COUNT, "Local", "CPU", "Count", "", "%d",
2053		 &lib_num_loc_cpus, 1, 0, NETPERF_TYPE_INT32);
2054
2055  set_output_elt(LOCAL_NODELAY, "Local", "NODELAY", "", "", "%d",
2056		 &loc_nodelay, 1, 0, NETPERF_TYPE_INT32);
2057
2058  set_output_elt(LOCAL_CORK, "Local", "Cork", "", "", "%d",
2059		 &loc_tcpcork, 1, 0, NETPERF_TYPE_INT32);
2060
2061  set_output_elt(RSS_SIZE_REQ, "Remote", "Send Socket", "Size", "Requested",
2062		 "%d", &rss_size_req, 1, 0, NETPERF_TYPE_INT32);
2063
2064  set_output_elt(RSS_SIZE, "Remote", "Send Socket", "Size", "Initial", "%d",
2065		 &rss_size, 1, 0, NETPERF_TYPE_INT32);
2066
2067  set_output_elt(RSS_SIZE_END, "Remote", "Send Socket", "Size", "Final", "%d",
2068		 &rss_size_end, 1, 0, NETPERF_TYPE_INT32);
2069
2070  set_output_elt(RSR_SIZE_REQ, "Remote", "Recv Socket", "Size", "Requested",
2071		 "%d", &rsr_size_req, 1, 0, NETPERF_TYPE_INT32);
2072
2073  set_output_elt(RSR_SIZE, "Remote", "Recv Socket", "Size", "Initial", "%d",
2074		 &rsr_size, 1, 0, NETPERF_TYPE_INT32);
2075
2076  set_output_elt(RSR_SIZE_END, "Remote", "Recv Socket", "Size", "Final", "%d",
2077		 &rsr_size_end, 1, 0, NETPERF_TYPE_INT32);
2078
2079  set_output_elt(REMOTE_SEND_SIZE, "Remote", "Send", "Size", "", "%d",
2080		 &remote_send_size, 1, 0, NETPERF_TYPE_INT32);
2081
2082  set_output_elt(REMOTE_RECV_SIZE, "Remote", "Recv", "Size", "", "%d",
2083		 &remote_recv_size, 1, 0, NETPERF_TYPE_INT32);
2084
2085  set_output_elt(REMOTE_SEND_CALLS, "Remote", "Send", "Calls", "", "%"PRIu64,
2086		 &remote_send_calls, 1, 0, NETPERF_TYPE_UINT64);
2087
2088  set_output_elt(REMOTE_RECV_CALLS, "Remote", "Recv", "Calls", "", "%"PRIu64,
2089		 &remote_receive_calls, 1, 0, NETPERF_TYPE_UINT64);
2090
2091  set_output_elt(REMOTE_BYTES_PER_RECV, "Remote", "Bytes", "Per", "Recv",
2092		 "%.2f", &remote_bytes_per_recv, 1, 0, NETPERF_TYPE_DOUBLE);
2093
2094  set_output_elt(REMOTE_BYTES_PER_SEND, "Remote", "Bytes", "Per", "Send",
2095		 "%.2f", &remote_bytes_per_send, 1, 0, NETPERF_TYPE_DOUBLE);
2096
2097  set_output_elt(REMOTE_BYTES_RECVD, "Remote", "Bytes", "Received", "",
2098		 "%"PRIu64, &remote_bytes_received, 1, 0, NETPERF_TYPE_UINT64);
2099
2100  set_output_elt(REMOTE_BYTES_SENT, "Remote", "Bytes", "Sent", "", "%"PRIu64,
2101		 &remote_bytes_sent, 1, 0, NETPERF_TYPE_UINT64);
2102
2103  set_output_elt(REMOTE_BYTES_XFERD, "Remote", "Bytes", "Xferred", "", "%.0f",
2104		 &remote_bytes_xferd, 1, 0, NETPERF_TYPE_DOUBLE);
2105
2106  set_output_elt(REMOTE_SEND_WIDTH, "Remote", "Send", "Width", "", "%d",
2107		 &remote_send_width, 1, 0, NETPERF_TYPE_INT32);
2108
2109  set_output_elt(REMOTE_RECV_WIDTH, "Remote", "Recv", "Width", "", "%d",
2110		 &remote_recv_width, 1, 0, NETPERF_TYPE_INT32);
2111
2112  set_output_elt(REMOTE_SEND_OFFSET, "Remote", "Send", "Offset", "", "%d",
2113		 &remote_send_offset, 1, 0, NETPERF_TYPE_INT32);
2114
2115  set_output_elt(REMOTE_RECV_OFFSET, "Remote", "Recv", "Offset", "", "%d",
2116		 &remote_recv_offset, 1, 0, NETPERF_TYPE_INT32);
2117
2118  set_output_elt(REMOTE_RECV_ALIGN, "Remote", "Recv", "Alignment", "", "%d",
2119		 &remote_recv_align, 1, 0, NETPERF_TYPE_INT32);
2120
2121  set_output_elt(REMOTE_SEND_ALIGN, "Remote", "Send", "Alignment", "", "%d",
2122		 &remote_send_align, 1, 0, NETPERF_TYPE_INT32);
2123
2124  set_output_elt(REMOTE_SEND_DIRTY_COUNT, "Remote", "Send", "Dirty", "Count",
2125		 "%d", &rem_dirty_count, 1, 0, NETPERF_TYPE_INT32);
2126
2127  set_output_elt(REMOTE_RECV_DIRTY_COUNT, "Remote", "Recv", "Dirty", "Count",
2128		 "%d", &rem_dirty_count, 1, 0, NETPERF_TYPE_INT32);
2129
2130  set_output_elt(REMOTE_RECV_CLEAN_COUNT, "Remote", "Recv", "Clean", "Count",
2131		 "%d", &rem_clean_count, 1, 0, NETPERF_TYPE_INT32);
2132
2133  set_output_elt(REMOTE_CPU_UTIL, "Remote", "CPU", "Util", "%", "%.2f",
2134		 &remote_cpu_utilization, 1, 0, NETPERF_TYPE_FLOAT);
2135
2136  set_output_elt(REMOTE_CPU_PERCENT_USER, "Remote", "CPU", "User", "%", "%.2f",
2137		 &lib_remote_cpu_stats.cpu_user, 1, 0, NETPERF_TYPE_FLOAT);
2138
2139  set_output_elt(REMOTE_CPU_PERCENT_SYSTEM,
2140                 "Remote", "CPU", "System", "%", "%.2f",
2141		 &lib_remote_cpu_stats.cpu_system, 1, 0, NETPERF_TYPE_FLOAT);
2142
2143  set_output_elt(REMOTE_CPU_PERCENT_IOWAIT,
2144                 "Remote", "CPU", "I/O", "%", "%.2f",
2145		 &lib_remote_cpu_stats.cpu_iowait, 1, 0, NETPERF_TYPE_FLOAT);
2146
2147  set_output_elt(REMOTE_CPU_PERCENT_IRQ,
2148                 "Remote", "CPU", "IRQ", "%", "%.2f",
2149		 &lib_remote_cpu_stats.cpu_irq, 1, 0, NETPERF_TYPE_FLOAT);
2150
2151  set_output_elt(REMOTE_CPU_PERCENT_SWINTR,
2152                 "Remote", "CPU", "swintr", "%", "%.2f",
2153		 &lib_remote_cpu_stats.cpu_swintr, 1, 0, NETPERF_TYPE_FLOAT);
2154
2155  set_output_elt(REMOTE_CPU_PEAK_UTIL, "Remote", "Peak", "Per CPU", "Util %",
2156		 "%.2f", &lib_remote_cpu_stats.peak_cpu_util, 1, 0,
2157                 NETPERF_TYPE_FLOAT);
2158
2159  set_output_elt(REMOTE_CPU_PEAK_ID, "Remote", "Peak", "Per CPU", "ID", "%d",
2160		 &lib_remote_cpu_stats.peak_cpu_id, 1, 0, NETPERF_TYPE_INT32);
2161
2162  set_output_elt(REMOTE_CPU_BIND, "Remote", "CPU", "Bind", "", "%d",
2163		 &remote_proc_affinity, 1, 0, NETPERF_TYPE_INT32);
2164
2165  set_output_elt(REMOTE_SD, "Remote", "Service", "Demand", "", "%.3f",
2166		 &remote_service_demand_double, 1, 0, NETPERF_TYPE_DOUBLE);
2167
2168  set_output_elt(REMOTE_CPU_METHOD, "Remote", "CPU", "Util", "Method", "%c",
2169		 &remote_cpu_method, 1, 0, NETPERF_TYPE_INT32);
2170
2171  set_output_elt(REMOTE_CPU_COUNT, "Remote", "CPU", "Count", "", "%d",
2172		 &lib_num_rem_cpus, 1, 0, NETPERF_TYPE_INT32);
2173
2174  set_output_elt(REMOTE_NODELAY, "Remote", "NODELAY", "", "", "%d",
2175		 &rem_nodelay, 1, 0, NETPERF_TYPE_INT32);
2176
2177  set_output_elt(REMOTE_CORK, "Remote", "Cork", "", "", "%d",
2178		 &rem_tcpcork, 1, 0, NETPERF_TYPE_INT32);
2179
2180  set_output_elt(LOCAL_DRIVER_NAME, "Local", "Driver", "Name", "", "%s",
2181		 deprecated_str, 1, OMNI_WANT_LOC_DRVINFO,
2182		 NETPERF_TYPE_CHAR);
2183
2184  set_output_elt(LOCAL_DRIVER_VERSION, "Local", "Driver", "Version", "", "%s",
2185		 deprecated_str, 1, OMNI_WANT_LOC_DRVINFO,
2186		 NETPERF_TYPE_CHAR);
2187
2188  set_output_elt(LOCAL_DRIVER_FIRMWARE, "Local", "Driver", "Firmware", "",
2189		 "%s", deprecated_str, 1, OMNI_WANT_LOC_DRVINFO,
2190		 NETPERF_TYPE_CHAR);
2191
2192  set_output_elt(LOCAL_DRIVER_BUS, "Local", "Driver", "Bus", "", "%s",
2193		 deprecated_str, 1, OMNI_WANT_LOC_DRVINFO, NETPERF_TYPE_CHAR);
2194
2195  set_output_elt(REMOTE_DRIVER_NAME, "Remote", "Driver", "Name", "", "%s",
2196		 deprecated_str, 1, OMNI_WANT_REM_DRVINFO,
2197		 NETPERF_TYPE_CHAR);
2198
2199  set_output_elt(REMOTE_DRIVER_VERSION, "Remote", "Driver", "Version", "",
2200		 "%s", deprecated_str, 1, OMNI_WANT_REM_DRVINFO,
2201		 NETPERF_TYPE_CHAR);
2202
2203  set_output_elt(REMOTE_DRIVER_FIRMWARE, "Remote", "Driver", "Firmware", "",
2204		 "%s", deprecated_str, 1, OMNI_WANT_REM_DRVINFO,
2205		 NETPERF_TYPE_CHAR);
2206
2207  set_output_elt(REMOTE_DRIVER_BUS, "Remote", "Driver", "Bus", "", "%s",
2208		 deprecated_str, 1, OMNI_WANT_REM_DRVINFO,
2209		 NETPERF_TYPE_CHAR);
2210
2211  set_output_elt(LOCAL_INTERFACE_SUBDEVICE, "Local", "Interface", "Subdevice",
2212		 "", "0x%.4x", &local_interface_subdevice, 1,
2213		 OMNI_WANT_LOC_IFIDS, NETPERF_TYPE_INT32);
2214
2215  set_output_elt(LOCAL_INTERFACE_DEVICE, "Local", "Interface", "Device", "",
2216		 "0x%.4x", &local_interface_device, 1, OMNI_WANT_LOC_IFIDS,
2217		 NETPERF_TYPE_INT32);
2218
2219  set_output_elt(LOCAL_INTERFACE_SUBVENDOR, "Local", "Interface", "Subvendor",
2220		 "", "0x%.4x", &local_interface_subvendor, 1,
2221		 OMNI_WANT_LOC_IFIDS, NETPERF_TYPE_UINT32);
2222
2223  set_output_elt(LOCAL_INTERFACE_VENDOR, "Local", "Interface", "Vendor", "",
2224		 "0x%.4x", &local_interface_vendor, 1, OMNI_WANT_LOC_IFIDS,
2225		 NETPERF_TYPE_UINT32);
2226
2227  set_output_elt(REMOTE_INTERFACE_SUBDEVICE, "Remote", "Interface",
2228		 "Subdevice", "", "0x%.4x", &remote_interface_subdevice, 1,
2229		 OMNI_WANT_REM_IFIDS, NETPERF_TYPE_UINT32);
2230
2231  set_output_elt(REMOTE_INTERFACE_DEVICE, "Remote", "Interface", "Device", "",
2232		 "0x%.4x", &remote_interface_device, 1, OMNI_WANT_REM_IFIDS,
2233		 NETPERF_TYPE_UINT32);
2234
2235  set_output_elt(REMOTE_INTERFACE_SUBVENDOR, "Remote", "Interface",
2236		 "Subvendor", "", "0x%.4x", &remote_interface_subvendor, 1,
2237		 OMNI_WANT_REM_IFIDS, NETPERF_TYPE_UINT32);
2238
2239  set_output_elt(REMOTE_INTERFACE_VENDOR, "Remote", "Interface", "Vendor", "",
2240		 "0x%.4x", &remote_interface_vendor, 1, OMNI_WANT_REM_IFIDS,
2241		 NETPERF_TYPE_UINT32);
2242
2243  set_output_elt(LOCAL_INTERFACE_NAME, "Local", "Interface", "Name", "", "%s",
2244		 deprecated_str, 1, OMNI_WANT_LOC_IFNAME,
2245		 NETPERF_TYPE_CHAR);
2246
2247  set_output_elt(REMOTE_INTERFACE_NAME, "Remote", "Interface", "Name", "",
2248		 "%s", deprecated_str, 1, OMNI_WANT_REM_IFNAME,
2249		 NETPERF_TYPE_CHAR);
2250
2251  set_output_elt(LOCAL_INTERFACE_SLOT, "Local", "Interface", "Slot", "", "%s",
2252		 deprecated_str, 1, OMNI_WANT_LOC_IFSLOT,
2253		 NETPERF_TYPE_CHAR);
2254
2255  set_output_elt(REMOTE_INTERFACE_SLOT,  "Remote",  "Interface",  "Slot",  "",
2256		 "%s",  deprecated_str, 1, OMNI_WANT_REM_IFSLOT,
2257		 NETPERF_TYPE_CHAR);
2258
2259  set_output_elt(REMOTE_MACHINE, "Remote", "Machine", "", "", "%s",
2260		 deprecated_str, 1, 0, NETPERF_TYPE_CHAR);
2261
2262  set_output_elt(REMOTE_VERSION, "Remote", "Version", "", "", "%s",
2263		 deprecated_str, 1, 0, NETPERF_TYPE_CHAR);
2264
2265  set_output_elt(REMOTE_RELEASE, "Remote", "Release", "", "", "%s",
2266		 deprecated_str, 1, 0, NETPERF_TYPE_CHAR);
2267
2268  set_output_elt(REMOTE_SYSNAME, "Remote", "Sysname", "", "", "%s",
2269		 deprecated_str, 1, 0, NETPERF_TYPE_CHAR);
2270
2271  set_output_elt(LOCAL_MACHINE, "Local", "Machine", "", "", "%s",
2272		 deprecated_str, 1, 0, NETPERF_TYPE_CHAR);
2273
2274  set_output_elt(LOCAL_VERSION, "Local", "Version", "", "", "%s",
2275		 deprecated_str, 1, 0, NETPERF_TYPE_CHAR);
2276
2277  set_output_elt(LOCAL_RELEASE, "Local", "Release", "", "", "%s",
2278		 deprecated_str, 1, 0, NETPERF_TYPE_CHAR);
2279
2280  set_output_elt(LOCAL_SYSNAME, "Local", "Sysname", "", "", "%s",
2281		 deprecated_str, 1, 0, NETPERF_TYPE_CHAR);
2282
2283  set_output_elt(REMOTE_INTERVAL_USECS, "Remote", "Interval", "Usecs", "",
2284		 "%d", &remote_interval_usecs, 1, 0, NETPERF_TYPE_INT32);
2285
2286  set_output_elt(REMOTE_INTERVAL_BURST, "Remote", "Interval", "Burst", "",
2287		 "%d", &remote_interval_burst, 1, 0, NETPERF_TYPE_INT32);
2288
2289  set_output_elt(LOCAL_SECURITY_ENABLED, "Local", "OS", "Security", "Enabled",
2290		 "%s", deprecated_str, 1, 0, NETPERF_TYPE_CHAR);
2291
2292  set_output_elt(LOCAL_SECURITY_TYPE, "Local", "OS", "Security", "Type", "%s",
2293		 deprecated_str, 1, 0, NETPERF_TYPE_CHAR);
2294
2295  set_output_elt(LOCAL_SECURITY_SPECIFIC, "Local", "OS", "Security",
2296		 "Specific", "%s", deprecated_str, 1, 0,
2297		 NETPERF_TYPE_CHAR);
2298
2299  set_output_elt(LOCAL_SECURITY_ENABLED_NUM, "Local", "OS", "Security",
2300		 "Enabled Num", "%d", &local_security_enabled_num, 1, 0,
2301		 NETPERF_TYPE_INT32);
2302
2303  set_output_elt(LOCAL_SECURITY_TYPE_ID, "Local", "OS", "Security", "Type ID",
2304		 "%d", &local_security_type_id, 1, 0, NETPERF_TYPE_INT32);
2305
2306  set_output_elt(REMOTE_SECURITY_ENABLED, "Remote", "OS", "Security",
2307		 "Enabled", "%s", deprecated_str, 1, 0,
2308		 NETPERF_TYPE_CHAR);
2309
2310  set_output_elt(REMOTE_SECURITY_TYPE, "Remote", "OS", "Security", "Type",
2311		 "%s", deprecated_str, 1, 0, NETPERF_TYPE_CHAR);
2312
2313  set_output_elt(REMOTE_SECURITY_SPECIFIC, "Remote", "OS", "Security",
2314		 "Specific", "%s", deprecated_str, 1, 0,
2315		 NETPERF_TYPE_CHAR);
2316
2317  set_output_elt(REMOTE_SECURITY_ENABLED_NUM, "Remote", "OS", "Security",
2318		 "Enabled", "%d", &remote_security_enabled_num, 1, 0,
2319		 NETPERF_TYPE_INT32);
2320
2321  set_output_elt(REMOTE_SECURITY_TYPE_ID, "Remote", "OS", "Security", "Type",
2322		 "%d", &remote_security_type_id, 1, 0, NETPERF_TYPE_INT32);
2323
2324  set_output_elt(LOCAL_INTERVAL_USECS, "Local", "Interval", "Usecs", "", "%d",
2325		 &interval_usecs, 1, 0, NETPERF_TYPE_INT32);
2326
2327  set_output_elt(LOCAL_INTERVAL_BURST, "Local", "Interval", "Burst", "", "%d",
2328		 &interval_burst, 1, 0, NETPERF_TYPE_INT32);
2329
2330  set_output_elt(REMOTE_SYSTEM_MODEL, "Remote", "System", "Model", "", "%s",
2331		 deprecated_str, 1, 0, NETPERF_TYPE_CHAR);
2332
2333  set_output_elt(REMOTE_CPU_MODEL, "Remote", "CPU", "Model", "", "%s",
2334		 deprecated_str, 1, 0, NETPERF_TYPE_CHAR);
2335
2336  set_output_elt(REMOTE_CPU_FREQUENCY, "Remote", "CPU", "Frequency", "MHz",
2337		 "%d", &remote_cpu_frequency, 1, 0, NETPERF_TYPE_INT32);
2338
2339  set_output_elt(LOCAL_SYSTEM_MODEL, "Local", "System", "Model", "", "%s",
2340		 deprecated_str, 1, 0, NETPERF_TYPE_CHAR);
2341
2342  set_output_elt(LOCAL_CPU_MODEL, "Local", "CPU", "Model", "", "%s",
2343		 deprecated_str, 1, 0, NETPERF_TYPE_CHAR);
2344
2345  set_output_elt(LOCAL_CPU_FREQUENCY, "Local", "CPU", "Frequency", "MHz", "%d",
2346		 &local_cpu_frequency, 1, 0, NETPERF_TYPE_INT32);
2347
2348  set_output_elt(MIN_LATENCY, "Minimum", "Latency", "Microseconds", "", "%d",
2349		 &min_latency, 0, OMNI_WANT_STATS, NETPERF_TYPE_INT32);
2350
2351  set_output_elt(MAX_LATENCY, "Maximum", "Latency", "Microseconds", "", "%d",
2352		 &max_latency, 0, OMNI_WANT_STATS, NETPERF_TYPE_INT32);
2353
2354  set_output_elt(P50_LATENCY, "50th", "Percentile", "Latency", "Microseconds",
2355		 "%d", &p50_latency, 0, OMNI_WANT_STATS, NETPERF_TYPE_INT32);
2356
2357  set_output_elt(P90_LATENCY, "90th", "Percentile", "Latency", "Microseconds",
2358		 "%d", &p90_latency, 0, OMNI_WANT_STATS, NETPERF_TYPE_INT32);
2359
2360  set_output_elt(P99_LATENCY, "99th", "Percentile", "Latency", "Microseconds",
2361		 "%d", &p99_latency, 0, OMNI_WANT_STATS, NETPERF_TYPE_INT32);
2362
2363  set_output_elt(MEAN_LATENCY, "Mean", "Latency", "Microseconds", "", "%.2f",
2364		 &mean_latency, 0, OMNI_WANT_STATS, NETPERF_TYPE_DOUBLE);
2365
2366  set_output_elt(STDDEV_LATENCY, "Stddev", "Latency", "Microseconds", "",
2367		 "%.2f", &stddev_latency, 0, OMNI_WANT_STATS, NETPERF_TYPE_DOUBLE);
2368
2369  set_output_elt(LOCAL_SOCKET_PRIO, "Local", "Socket", "Priority", "", "%d",
2370		 &local_socket_prio, 1, 0, NETPERF_TYPE_INT32);
2371
2372  set_output_elt(REMOTE_SOCKET_PRIO, "Remote", "Socket", "Priority", "", "%d"
2373		 , &remote_socket_prio, 1, 0, NETPERF_TYPE_INT32);
2374
2375  set_output_elt(LOCAL_SOCKET_TOS, "Local", "Socket", "TOS", "", "0x%.2x",
2376		 &local_socket_tos, 1, 0, NETPERF_TYPE_INT32);
2377
2378  set_output_elt(REMOTE_SOCKET_TOS, "Remote", "Socket", "TOS", "", "0x%.2x",
2379		 &remote_socket_tos, 1, 0, NETPERF_TYPE_INT32);
2380
2381  set_output_elt(LOCAL_CONG_CONTROL, "Local", "Congestion", "Control",
2382		 "Algorithm", "%s", local_cong_control, 0,
2383		 OMNI_WANT_LOC_CONG, NETPERF_TYPE_CHAR);
2384
2385  set_output_elt(REMOTE_CONG_CONTROL, "Remote", "Congestion", "Control",
2386		 "Algorithm", "%s", remote_cong_control, 0,
2387		 OMNI_WANT_REM_CONG, NETPERF_TYPE_CHAR);
2388
2389  set_output_elt(LOCAL_FILL_FILE, "Local", "Fill", "File", "", "%s",
2390		 local_fill_file, 0, 0, NETPERF_TYPE_CHAR);
2391
2392  set_output_elt(REMOTE_FILL_FILE, "Remote", "Fill", "File", "", "%s",
2393		 remote_fill_file, 0, 0, NETPERF_TYPE_CHAR);
2394
2395  set_output_elt(OUTPUT_END, "This", "Is", "The", "End", "%s",
2396		 NULL, 0, 0, NETPERF_TYPE_CHAR);
2397
2398}
2399
2400void
2401print_omni_init() {
2402
2403  int i,j;
2404
2405  if (debug) {
2406    fprintf(where,"%s entered\n",
2407	    __FUNCTION__);
2408    fflush(where);
2409  }
2410
2411  /* why is this before the if you ask? because some of the output
2412     specifiers are char * rather than char[] and when I wanted to
2413     start setting output_group flags I was needing to call
2414     print_omni_init() before the char * 's were malloced, which meant
2415     the netperf_output_source got NULL pointers.  there is
2416     undoubtedly a cleaner way to do all this. raj 20110629 */
2417
2418  print_omni_init_list();
2419
2420  if (printing_initialized) return;
2421
2422  printing_initialized = 1;
2423
2424
2425  /* belts and suspenders */
2426  for (j = 0; j < NETPERF_MAX_BLOCKS; j++)
2427    for (i = 0; i < NETPERF_OUTPUT_MAX; i++)
2428      output_list[j][i] = OUTPUT_END;
2429
2430
2431  if (output_selection_spec) {
2432      parse_output_selection(output_selection_spec);
2433  }
2434  else {
2435      set_output_list_by_test();
2436  }
2437
2438}
2439
2440/* why? because one cannot simply pass a pointer to snprintf - well
2441   except when it is expecting one... */
2442int
2443my_snprintf(char *buffer, size_t size, netperf_output_elt_t *output_elt)
2444{
2445  switch (output_elt->output_type) {
2446  case NETPERF_TYPE_CHAR:
2447    return snprintf(buffer, size,
2448		    output_elt->format,
2449		    (char *)output_elt->display_value);
2450    break;
2451  case NETPERF_TYPE_INT32:
2452    return snprintf(buffer, size,
2453		    output_elt->format,
2454		    *(int *)(output_elt->display_value));
2455    break;
2456  case NETPERF_TYPE_UINT32:
2457    return snprintf(buffer, size,
2458		    output_elt->format,
2459		    *(unsigned int *)(output_elt->display_value));
2460    break;
2461  case NETPERF_TYPE_INT64:
2462    return snprintf(buffer, size,
2463		    output_elt->format,
2464		    *(long long *)(output_elt->display_value));
2465    break;
2466  case NETPERF_TYPE_UINT64:
2467    return snprintf(buffer, size,
2468		    output_elt->format,
2469		    *(unsigned long long *)(output_elt->display_value));
2470    break;
2471  case NETPERF_TYPE_FLOAT:
2472    return snprintf(buffer, size,
2473		    output_elt->format,
2474		    *(float *)(output_elt->display_value));
2475    break;
2476  case NETPERF_TYPE_DOUBLE:
2477    return snprintf(buffer, size,
2478		    output_elt->format,
2479		    *(double *)(output_elt->display_value));
2480    break;
2481  default:
2482    fprintf(stderr,
2483	    "Unknown/unsupported output_elt output_type of %d\n",
2484	    output_elt->output_type);
2485    fflush(stderr);
2486    exit(-1);
2487  }
2488}
2489
2490void
2491print_omni_csv()
2492{
2493
2494  int i,j,k,buflen,vallen;
2495
2496  char *hdr1 = NULL;
2497  char *val1 = NULL;
2498  char *h1 = NULL;
2499  char *v1 = NULL;
2500  char tmpval[1024];
2501
2502  buflen = 0;
2503  for (i = 0; i < NETPERF_MAX_BLOCKS; i++) {
2504    for (j = 0;
2505	 ((j < NETPERF_OUTPUT_MAX) &&
2506	  (output_list[i][j] != OUTPUT_END));
2507	 j++) {
2508      if ((netperf_output_source[output_list[i][j]].format != NULL) &&
2509	  (netperf_output_source[output_list[i][j]].display_value != NULL)) {
2510	vallen =
2511	  my_snprintf(tmpval,
2512		      1024,
2513		      &(netperf_output_source[output_list[i][j]]));
2514	if (vallen == -1) {
2515	  fprintf(where,"my_snprintf failed on %s with format %s\n",
2516		  netperf_output_enum_to_str(j),
2517		  netperf_output_source[output_list[i][j]].format);
2518	  fflush(where);
2519	}
2520	vallen += 1; /* forget not the terminator */
2521      }
2522      else
2523	vallen = 0;
2524
2525      if (vallen >
2526	  netperf_output_source[output_list[i][j]].tot_line_len)
2527	netperf_output_source[output_list[i][j]].tot_line_len = vallen;
2528
2529      buflen +=
2530	netperf_output_source[output_list[i][j]].tot_line_len;
2531    }
2532  }
2533
2534  if (print_headers) hdr1 = malloc(buflen + 1);
2535  val1 = malloc(buflen + 1);
2536
2537  if (((hdr1 == NULL) && (print_headers)) ||
2538      (val1 == NULL)) {
2539    fprintf(where,"unable to allocate output buffers\n");
2540    fflush(where);
2541    exit(-1);
2542  }
2543
2544  if (print_headers) memset(hdr1,' ',buflen + 1);
2545  memset(val1,' ',buflen + 1);
2546
2547  /* ostensibly, we now "know" that we have enough space in all our
2548     strings, and we have spaces where we want them etc */
2549  h1 = hdr1;
2550  v1 = val1;
2551  for (i = 0; i < NETPERF_MAX_BLOCKS; i++) {
2552    for (j = 0;
2553	 ((j < NETPERF_OUTPUT_MAX) &&
2554	  (output_list[i][j] != OUTPUT_END));
2555	 j++) {
2556      int len;
2557      len = 0;
2558      if (print_headers) {
2559	for (k = 0; ((k < 4) &&
2560		     (NULL !=
2561		      netperf_output_source[output_list[i][j]].line[k]) &&
2562		     (strcmp("",netperf_output_source[output_list[i][j]].line[k]))); k++) {
2563
2564	  len = sprintf(h1,
2565			"%s",
2566			netperf_output_source[output_list[i][j]].line[k]);
2567	  *(h1 + len) = ' ';
2568	  /* now move to the next starting column. for csv we aren't worried
2569	     about alignment between the header and the value lines */
2570	  h1 += len + 1;
2571	}
2572	*(h1 - 1) = ',';
2573      }
2574      if ((netperf_output_source[output_list[i][j]].format != NULL) &&
2575	  (netperf_output_source[output_list[i][j]].display_value != NULL)) {
2576	/* tot_line_len is bogus here, but should be "OK" ? */
2577	len = my_snprintf(v1,
2578			  netperf_output_source[output_list[i][j]].tot_line_len,
2579			  &(netperf_output_source[output_list[i][j]]));
2580
2581	/* nuke the trailing \n" from the string routine.  */
2582	*(v1 + len) = ',';
2583	v1 += len + 1;
2584      }
2585      else {
2586	/* we need a ',' even if there is no value */
2587	*v1 = ',';
2588	v1 += 2;
2589      }
2590    }
2591  }
2592
2593  /* ok, _now_ null terminate each line by nuking the last comma.  do
2594     we have an OBOB here? */
2595  if (print_headers) *(h1-1) = 0;
2596  *(v1-1) = 0;
2597  /* and now spit it out, but only if it is going to have something
2598     in it. we don't want a bunch of blank lines or nulls...  */
2599  if (output_list[0][0] != OUTPUT_END) {
2600    if (print_headers) printf("%s\n",hdr1);
2601    printf("%s\n",val1);
2602  }
2603
2604  if (hdr1 != NULL) free(hdr1);
2605  if (val1 != NULL) free(val1);
2606
2607}
2608
2609void
2610print_omni_keyword()
2611{
2612  /* this one should be the simplest of all - no buffers to allocate,
2613     just spit it all out. raj 20080805 */
2614
2615  int i,j;
2616  char tmpval[1024];
2617  int vallen;
2618
2619  for (i = 0; i < NETPERF_MAX_BLOCKS; i++) {
2620    for (j = 0;
2621	 ((j < NETPERF_OUTPUT_MAX) &&
2622	  (output_list[i][j] != OUTPUT_END));
2623	 j++) {
2624      if ((netperf_output_source[output_list[i][j]].format != NULL) &&
2625	  (netperf_output_source[output_list[i][j]].display_value != NULL)) {
2626	vallen =
2627	  my_snprintf(tmpval,
2628		      1024,
2629		      &(netperf_output_source[output_list[i][j]]));
2630	if (vallen == -1) {
2631	  snprintf(tmpval,
2632		   1024,
2633		   "my_snprintf failed with format %s\n",
2634		   netperf_output_source[output_list[i][j]].format);
2635	}
2636	fprintf(where,
2637		"%s=%s\n",netperf_output_enum_to_str(output_list[i][j]),
2638		tmpval);
2639      }
2640    }
2641  }
2642  fflush(where);
2643}
2644
2645void
2646print_omni_human()
2647{
2648
2649  int i,j,k,buflen,buflen_max;
2650
2651  char *hdr[4];
2652  char *val1 = NULL;
2653  char tmpval[1024];  /* excessive, but we may have the command line */
2654  int  vallen;
2655
2656  for (k = 0; k < 4; k ++) {
2657    hdr[k] = NULL;
2658  }
2659
2660  /* decisions, decisions... walk the list twice to only need to
2661     allocate the charcter buffers once, or walk it once and possibly
2662     reallocate them as I go... oh, lets walk it twice just for fun to
2663     start. since only now do we know that the values are around to be
2664     printed, we should try the snprintf for the value and see how
2665     much space it wants and update max_line_len accordingly */
2666  buflen_max = 0;
2667  for (i = 0; i < NETPERF_MAX_BLOCKS; i++) {
2668    buflen = 0;
2669    for (j = 0;
2670	 ((j < NETPERF_OUTPUT_MAX) &&
2671	  (output_list[i][j] != OUTPUT_END));
2672	 j++) {
2673      if ((netperf_output_source[output_list[i][j]].format != NULL) &&
2674	  (netperf_output_source[output_list[i][j]].display_value !=
2675	   NULL))
2676	/* need to count the \n */
2677	vallen = my_snprintf(tmpval,
2678			     1024,
2679			     &(netperf_output_source[output_list[i][j]])) + 1;
2680      else
2681	vallen = 0;
2682
2683      if (vallen >
2684	  netperf_output_source[output_list[i][j]].max_line_len)
2685	netperf_output_source[output_list[i][j]].max_line_len = vallen;
2686
2687      buflen +=
2688	netperf_output_source[output_list[i][j]].max_line_len + 1;
2689    }
2690
2691    if (buflen > buflen_max)
2692      buflen_max = buflen;
2693  }
2694
2695  /* more belts and suspenders */
2696  for (k = 0; (k < 4) && (print_headers); k++) {
2697    hdr[k] = malloc(buflen_max+1);
2698  }
2699  val1 = malloc(buflen_max+1);
2700
2701  /* we could probably be more succinct here but perhaps the compiler
2702     can figure that out for us :) */
2703  for (k = 0; (k < 4) && (print_headers); k++) {
2704    if (hdr[k] == NULL) {
2705      fprintf(where,"Unable to allocate output buffers\n");
2706      fflush(where);
2707      exit(-1);
2708    }
2709  }
2710
2711  /* ostensibly, we now "know" that we have enough space in all our
2712     strings, and we have spaces where we want them etc */
2713  for (i = 0; i < NETPERF_MAX_BLOCKS; i++) {
2714    char *h[4];
2715    char *v1 = val1;
2716
2717    for (k = 0; k < 4; k++) h[k] = hdr[k];
2718
2719    /* we want to blank things out each time since we skip around a lot */
2720    for (k = 0; (k < 4) && (print_headers); k++) {
2721      memset(hdr[k],' ',buflen_max+1);
2722    }
2723    memset(val1,' ',buflen_max+1);
2724
2725
2726    for (j = 0;
2727	 ((j < NETPERF_OUTPUT_MAX) &&
2728	  (output_list[i][j] != OUTPUT_END));
2729	 j++) {
2730      if (print_headers) {
2731	for (k = 0; k < 4; k++) {
2732	  memcpy(h[k],
2733		 netperf_output_source[output_list[i][j]].line[k],
2734		 strlen(netperf_output_source[output_list[i][j]].line[k]));
2735	}
2736      }
2737      if ((netperf_output_source[output_list[i][j]].format != NULL) &&
2738	  (netperf_output_source[output_list[i][j]].display_value != NULL)) {
2739	int len;
2740	len = my_snprintf(v1,
2741			  netperf_output_source[output_list[i][j]].max_line_len,
2742			  &(netperf_output_source[output_list[i][j]]));
2743	/* nuke the trailing \n" from the string routine.  */
2744	*(v1 + len) = ' ';
2745      }
2746      /* now move to the next starting column */
2747    for (k = 0; (k < 4) && (print_headers); k++) {
2748	h[k] +=
2749	  netperf_output_source[output_list[i][j]].max_line_len + 1;
2750      }
2751      v1 += netperf_output_source[output_list[i][j]].max_line_len + 1;
2752    }
2753    /* ok, _now_ null terminate each line.  do we have an OBOB here? */
2754    for (k = 0; (k < 4) && (print_headers); k++) {
2755      *h[k] = 0;
2756    }
2757    *v1 = 0;
2758    /* and now spit it out, but only if it is going to have something
2759       in it. we don't want a bunch of blank lines or nulls... at some
2760     point we might want to work backwards collapsine whitespace from
2761     the right but for now, we won't bother */
2762    if (output_list[i][0] != OUTPUT_END) {
2763      if (i > 0) printf("\n"); /* we want a blank line between blocks ? */
2764      for (k = 0; (k < 4) && (print_headers); k++) {
2765	printf("%s\n",hdr[k]);
2766      }
2767      printf("%s\n",val1);
2768    }
2769  };
2770  for (k = 0; k < 4; k++) {
2771    if (hdr[k] != NULL) free(hdr[k]);
2772  }
2773}
2774
2775void
2776print_omni()
2777{
2778
2779  print_omni_init();
2780
2781  if (debug > 2)
2782    dump_netperf_output_source(where);
2783
2784  switch (netperf_output_mode) {
2785  case CSV:
2786    print_omni_csv();
2787    break;
2788  case KEYVAL:
2789    print_omni_keyword();
2790    break;
2791  case HUMAN:
2792    print_omni_human();
2793    break;
2794  default:
2795    fprintf(where,"Yo Rick! There is a bug in netperf_output_mode!\n");
2796    fflush(where);
2797    exit(-1);
2798  }
2799
2800}
2801/* for the next few routines (connect, accept, send, recv,
2802   disconnect/close) we will use a return of -1 to mean times up, -2
2803   to mean a transient error (eg ENOBUFS on a UDP send call) and -3 to
2804   mean hard error.  this means it is ok for the connect routine to
2805   return a 0 (zero) if that happens to be the fd/SOCKET we get and in
2806   theory we will be able to support zero-length messages on those
2807   protocols which support it.  all in theory of course. raj
2808   2008-01-09 */
2809
2810int
2811connect_data_socket(SOCKET send_socket, struct addrinfo *remote_res, int dont_give_up)
2812{
2813  int ret;
2814
2815  /* Connect up to the remote port on the data socket  */
2816  if ((ret = connect(send_socket,
2817		     remote_res->ai_addr,
2818		     remote_res->ai_addrlen)) == INVALID_SOCKET) {
2819    if (SOCKET_EINTR(ret))  {
2820      /* we interpret this to mean that the test is supposed to be
2821	 over, so return a value of -1 to the caller */
2822      return -1;
2823    }
2824    if ((SOCKET_EADDRINUSE(ret)) || SOCKET_EADDRNOTAVAIL(ret) || dont_give_up) {
2825      /* likely something our explicit bind() would have caught in
2826	 the past, so go get another port, via create_data_socket.
2827	 yes, this is a bit more overhead than before, but the
2828	 condition should be rather rare. we only get a new port if
2829	 this was a connection-including test like TCP_CRR or
2830	 TCP_CC. Otherwise we need to return an error. raj
2831	 2008-01-08 */
2832      return -2;
2833    }
2834    else
2835      /* -3 means there was an error */
2836      return -3;
2837  }
2838  return 0;
2839}
2840
2841static
2842int send_pktinfo(SOCKET data_socket, char *buffer, int len, struct sockaddr *destination, int destlen) {
2843#ifdef IP_PKTINFO
2844  struct msghdr msg;
2845  struct iovec iovec[1];
2846  char msg_control[512];
2847  struct cmsghdr *cmsg;
2848  int cmsg_space = 0;
2849
2850  iovec[0].iov_base = buffer;
2851  iovec[0].iov_len = len;
2852  msg.msg_name = destination;
2853  msg.msg_namelen = destlen;
2854  msg.msg_iov = iovec;
2855  msg.msg_iovlen = 1;
2856  msg.msg_control = msg_control;
2857  msg.msg_controllen = sizeof(msg_control);
2858  msg.msg_flags = 0;
2859
2860  cmsg = CMSG_FIRSTHDR(&msg);
2861  if (have_pktinfo) {
2862    cmsg->cmsg_level = IPPROTO_IP;
2863    cmsg->cmsg_type = IP_PKTINFO;
2864    cmsg->cmsg_len = CMSG_LEN(sizeof(in_pktinfo));
2865    *(struct in_pktinfo*)CMSG_DATA(cmsg) = in_pktinfo;
2866    cmsg_space += CMSG_SPACE(sizeof(in_pktinfo));
2867  }
2868  msg.msg_controllen = cmsg_space;
2869  return sendmsg(data_socket, &msg, 0);
2870#else
2871  return -1;
2872#endif /* IP_PKTINFO */
2873}
2874
2875
2876int
2877send_data(SOCKET data_socket, struct ring_elt *send_ring, uint32_t bytes_to_send, struct sockaddr *destination, int destlen, int protocol) {
2878
2879  int len;
2880
2881  /* if the user has supplied a destination, we use sendto, otherwise
2882     we use send.  we ass-u-me blocking operations always, so no need
2883     to check for eagain or the like. */
2884
2885  if (debug > 2) {
2886    fprintf(where,
2887	    "%s sock %d, ring elt %p, bytes %d, dest %p, len %d\n",
2888	    __FUNCTION__,
2889	    data_socket,
2890	    send_ring,
2891	    bytes_to_send,
2892	    destination,
2893	    destlen);
2894    fflush(where);
2895  }
2896
2897  if (destination) {
2898    if (have_pktinfo) {
2899      len = send_pktinfo(data_socket,
2900			 send_ring->buffer_ptr,
2901			 bytes_to_send,
2902			 destination,
2903			 destlen);
2904    }
2905    else {
2906      len = sendto(data_socket,
2907		   send_ring->buffer_ptr,
2908		   bytes_to_send,
2909#if defined(MSG_FASTOPEN)
2910		   (use_fastopen && protocol == IPPROTO_TCP) ? MSG_FASTOPEN : 0,
2911#else
2912		   0,
2913#endif
2914		   destination,
2915		   destlen);
2916    }
2917  }
2918  else {
2919    if (!use_write) {
2920      len = send(data_socket,
2921		 send_ring->buffer_ptr,
2922		 bytes_to_send,
2923		 0);
2924    }
2925    else {
2926#ifndef WIN32
2927      len = write(data_socket,
2928		  send_ring->buffer_ptr,
2929		  bytes_to_send);
2930#else
2931      fprintf(where,"I'm sorry Dave I cannot write() under Windows\n");
2932      fflush(where);
2933      return -3;
2934#endif
2935    }
2936  }
2937  if(len != bytes_to_send) {
2938    /* don't forget that some platforms may do a partial send upon
2939       receipt of the interrupt and not return an EINTR... */
2940    if (SOCKET_EINTR(len) || (len >= 0))
2941      {
2942	/* we hit the end of a  timed test. */
2943	return -1;
2944      }
2945    /* if this is UDP it is possible to receive an ENOBUFS on the send
2946       call and it would not be a fatal error.  of course if we were
2947       to return 0 then it would make the test think it was over when
2948       it really wasn't.  the question becomes what to do.  for the
2949       time being, the answer will likely be to return something like
2950       -2 to indicate a non-fatal error happened on the send and let
2951       the caller figure it out :) we won't actually check to see if
2952       this is UDP - it is the author's experience in many, Many, MANY
2953       years that the only time an ENOBUFS has been returned in a
2954       netperf test has been with UDP.  famous last words :) */
2955    if (errno == ENOBUFS)
2956      return -2;
2957    else {
2958      fprintf(where,"%s: data send error: %s (errno %d)\n",
2959	      __FUNCTION__, strerror(errno), errno);
2960      return -3;
2961    }
2962  }
2963  return len;
2964}
2965
2966#if defined(__linux)
2967static int
2968recv_data_no_copy(SOCKET data_socket, struct ring_elt *recv_ring, uint32_t bytes_to_recv, struct sockaddr *source, netperf_socklen_t *sourcelen, uint32_t flags, uint32_t *num_receives) {
2969
2970#ifndef SPLICE_F_MOVE
2971# define SPLICE_F_MOVE 0x01
2972#endif
2973#ifndef SPLICE_F_NONBLOCK
2974# define SPLICE_F_NONBLOCK 0x02
2975#endif
2976
2977  static int pfd[2] = {-1, -1};
2978  static int fdnull = -1;
2979
2980
2981  char *temp_message_ptr;
2982  int bytes_left;
2983  int bytes_recvd;
2984  int my_recvs;
2985  int my_flags = SPLICE_F_MOVE | SPLICE_F_NONBLOCK; /* values
2986						       suggested by
2987						       Eric Dumazet */
2988  int ret;
2989
2990  if (pfd[0] == -1) {
2991    if (pipe(pfd)) {
2992      fprintf(where,
2993	      "%s pipe call failed with errno %d '%s'\n",
2994	      __FUNCTION__,
2995	      errno,
2996	      strerror(errno));
2997      return -4;  /* this will cause recv_data to do things the
2998		     old-fashioned way for the test */
2999    }
3000    if ((fdnull = open("/dev/null",O_WRONLY)) == -1) {
3001      fprintf(where,
3002	      "%s open call failed with errno %d '%s'\n",
3003	      __FUNCTION__,
3004	      errno,
3005	      strerror(errno));
3006      return -4;
3007    }
3008  }
3009
3010  /* receive data off the data_socket, ass-u-me-ing a blocking socket
3011     all the way!-) 2008-01-08 */
3012  my_recvs = 0;
3013  bytes_left = bytes_to_recv;
3014
3015  if (debug > 1) {
3016    fprintf(where,
3017	    "%s sock %d, ring elt %p, bytes %d, source %p, srclen %d, flags %x, num_recv %p\n",
3018	    __FUNCTION__,
3019	    data_socket,
3020	    recv_ring,
3021	    bytes_to_recv,
3022	    source,
3023	    (source != NULL) ? *sourcelen : -1,
3024	    flags,
3025	    num_receives);
3026    fflush(where);
3027  }
3028  do {
3029
3030    bytes_recvd = splice(data_socket,
3031			 NULL,
3032			 pfd[1],
3033			 NULL,
3034			 bytes_left,
3035			 my_flags);
3036
3037
3038    if (bytes_recvd > 0) {
3039      /* per Eric Dumazet, we should just let this second splice call
3040	 move as many bytes as it can and not worry about how much.
3041	 this should make the call more robust when made on a system
3042	 under memory pressure */
3043      splice(pfd[0], NULL, fdnull, NULL, 1 << 30, my_flags);
3044      bytes_left -= bytes_recvd;
3045    }
3046    else {
3047      break;
3048    }
3049    my_recvs++; /* should the pair of splices count as one? */
3050  } while ((bytes_left > 0) && (flags & NETPERF_WAITALL));
3051
3052  *num_receives = my_recvs;
3053
3054  /* OK, we are out of the loop - now what? */
3055  if (bytes_recvd < 0) {
3056    /* did the timer hit, or was there an error? */
3057    if (SOCKET_EINTR(bytes_recvd))
3058      {
3059	/* We hit the end of a timed test. */
3060	return -1;
3061      }
3062    /* it was a hard error */
3063    return -3;
3064  }
3065
3066
3067  /* this looks a little funny, but should be correct.  if we had
3068     NETPERF_WAITALL set and we got here, it means we got all the
3069     bytes of the request/response.  otherwise we would have hit the
3070     error or end of test cases.  if NETPERF_WAITALL isn't set, this
3071     is a STREAM test, and we will have only made one call to recv, so
3072     bytes_recvd will be accurate. */
3073  if (bytes_left)
3074    return bytes_recvd;
3075  else
3076    return bytes_to_recv;
3077
3078}
3079
3080#endif
3081
3082static
3083int recv_pktinfo(SOCKET data_socket, char *message_ptr, int bytes_to_recv,  int my_flags, struct sockaddr *source, netperf_socklen_t *sourcelen) {
3084
3085#ifdef IP_PKTINFO
3086  struct iovec  my_iovec;
3087  struct msghdr my_header;
3088  struct cmsghdr *cmsg;
3089  struct in_pktinfo *pktinfo;
3090
3091  char control_buf[512];
3092  int onoff = 1;
3093  int ret;
3094
3095  my_iovec.iov_base = message_ptr;
3096  my_iovec.iov_len = bytes_to_recv;
3097
3098  my_header.msg_name = source;
3099  my_header.msg_namelen = *sourcelen;
3100  my_header.msg_iov = &my_iovec;
3101  my_header.msg_iovlen = 1;
3102  my_header.msg_control = control_buf;
3103  my_header.msg_controllen = sizeof(control_buf);
3104
3105  /* not going to bother checking, if it doesn't work we are no
3106     worse-off than we were before. we are going to ignore IPv6 for
3107     the time being */
3108  setsockopt(data_socket, IPPROTO_IP, IP_PKTINFO, &onoff, sizeof(onoff));
3109
3110  ret = recvmsg(data_socket, &my_header, 0);
3111
3112  if (ret >= 0) {
3113    struct sockaddr_in me;
3114    struct sockaddr_in clear;
3115    netperf_socklen_t melen = sizeof(me);
3116    for (cmsg = CMSG_FIRSTHDR(&my_header);
3117	 cmsg != NULL;
3118	 cmsg = CMSG_NXTHDR(&my_header, cmsg)) {
3119      if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO) {
3120	in_pktinfo = *(struct in_pktinfo *)CMSG_DATA(cmsg);
3121	have_pktinfo = 1;
3122      }
3123    }
3124  }
3125
3126  onoff = 0;
3127  setsockopt(data_socket, IPPROTO_IP, IP_PKTINFO, &onoff, sizeof(onoff));
3128
3129  return ret;
3130#else
3131  return -1;
3132#endif
3133}
3134
3135
3136int
3137recv_data(SOCKET data_socket, struct ring_elt *recv_ring, uint32_t bytes_to_recv, struct sockaddr *source, netperf_socklen_t *sourcelen, uint32_t flags, uint32_t *num_receives) {
3138
3139  char *temp_message_ptr;
3140  int bytes_left;
3141  int bytes_recvd;
3142  int my_recvs;
3143  int my_flags = 0; /* will we one day want to set MSG_WAITALL? */
3144
3145#if defined(__linux)
3146  int ret;
3147  if (loc_rcvavoid == 1) {
3148    ret = recv_data_no_copy(data_socket, recv_ring, bytes_to_recv, source, sourcelen, flags, num_receives);
3149    if (ret != -4)
3150      return ret;
3151    else
3152      loc_rcvavoid = 0;
3153  }
3154#endif
3155
3156  /* receive data off the data_socket, ass-u-me-ing a blocking socket
3157     all the way!-) 2008-01-08 */
3158  my_recvs = 0;
3159  bytes_left = bytes_to_recv;
3160  temp_message_ptr  = recv_ring->buffer_ptr;
3161
3162  if (debug > 1) {
3163    fprintf(where,
3164	    "%s sock %d, ring elt %p, bytes %d, source %p, srclen %d, flags %x, num_recv %p\n",
3165	    __FUNCTION__,
3166	    data_socket,
3167	    recv_ring,
3168	    bytes_to_recv,
3169	    source,
3170	    (source != NULL) ? *sourcelen : -1,
3171	    flags,
3172	    num_receives);
3173    fflush(where);
3174  }
3175  do {
3176    if (source) {
3177      /* call recvfrom it does look a little silly here inside the do
3178	 while, but I think it is ok - a UDP or other DGRAM or
3179	 SEQPACKET (?) socket, which should be the only time we
3180	 pass-in a source pointer will have a semantic that should get
3181	 us out of the dowhile on the first call anyway.  if it
3182	 turns-out not to be the case, then we can hoist the if above
3183	 the do and put the dowhile in the else. */
3184      if (use_pktinfo) {
3185	bytes_recvd = recv_pktinfo(data_socket,
3186				   temp_message_ptr,
3187				   bytes_left,
3188				   my_flags,
3189				   source,
3190				   sourcelen);
3191	use_pktinfo = 0;
3192      }
3193      else {
3194	bytes_recvd = recvfrom(data_socket,
3195			       temp_message_ptr,
3196			       bytes_left,
3197			       my_flags,
3198			       source,
3199			       sourcelen);
3200      }
3201    }
3202    else {
3203      /* just call recv */
3204      bytes_recvd = recv(data_socket,
3205			 temp_message_ptr,
3206			 bytes_left,
3207			 my_flags);
3208    }
3209    if (bytes_recvd > 0) {
3210      bytes_left -= bytes_recvd;
3211      temp_message_ptr += bytes_recvd;
3212    }
3213    else {
3214      break;
3215    }
3216    my_recvs++;
3217  } while ((bytes_left > 0) && (flags & NETPERF_WAITALL));
3218
3219  *num_receives = my_recvs;
3220
3221  /* OK, we are out of the loop - now what? */
3222  if (bytes_recvd < 0) {
3223    /* did the timer hit, or was there an error? */
3224    if (SOCKET_EINTR(bytes_recvd))
3225      {
3226	/* We hit the end of a timed test. */
3227	return -1;
3228      }
3229    if (SOCKET_EAGAIN(bytes_recvd) ||
3230	SOCKET_EWOULDBLOCK(bytes_recvd)) {
3231      return -2;
3232    }
3233    /* it was a hard error */
3234    return -3;
3235  }
3236
3237
3238  /* this looks a little funny, but should be correct.  if we had
3239     NETPERF_WAITALL set and we got here, it means we got all the
3240     bytes of the request/response.  otherwise we would have hit the
3241     error or end of test cases.  if NETPERF_WAITALL isn't set, this
3242     is a STREAM test, and we will have only made one call to recv, so
3243     bytes_recvd will be accurate. */
3244  if (bytes_left)
3245    return bytes_recvd;
3246  else
3247    return bytes_to_recv;
3248
3249}
3250
3251
3252int
3253close_data_socket(SOCKET data_socket, struct sockaddr *peer, int peerlen, int protocol)
3254{
3255
3256  int ret;
3257  char buffer[4];
3258
3259  if (debug) {
3260    fprintf(where,
3261	    "%s sock %d peer %p peerlen %d protocol %d\n",
3262	    __FUNCTION__,
3263	    data_socket,
3264	    peer,
3265	    peerlen,
3266	    protocol);
3267    fflush(where);
3268  }
3269
3270  if (protocol == IPPROTO_UDP) {
3271    /* try to give the remote a signal. what this means if we ever
3272       wanted to actually send zero-length messages remains to be seen
3273       :)  */
3274    int i;
3275    for (i = 0; i < 3; i++) {
3276      if (peer)
3277	ret = sendto(data_socket,
3278		     buffer,
3279		     0,
3280		     0,
3281		     peer,
3282		     peerlen);
3283      else
3284	ret = send(data_socket,
3285		   buffer,
3286		   0,
3287		   0);
3288      if (SOCKET_EINTR(ret)) {
3289	close(data_socket);
3290	return -1;
3291      }
3292    }
3293  }
3294  ret = close(data_socket);
3295
3296  if (SOCKET_EINTR(ret)) {
3297    /* end of test */
3298    return -1;
3299  }
3300  else if (ret == 0) {
3301    return ret;
3302  }
3303  else
3304    return -3;
3305
3306}
3307
3308int
3309disconnect_data_socket(SOCKET data_socket, int initiate, int do_close, struct sockaddr *peer, int peerlen)
3310{
3311
3312  char buffer[4];
3313  int bytes_recvd;
3314
3315  if (debug) {
3316    fprintf(where,
3317	    "%s sock %d init %d do_close %d protocol %d\n",
3318	    __FUNCTION__,
3319	    data_socket,
3320	    initiate,
3321	    do_close,
3322	    protocol);
3323    fflush(where);
3324  }
3325
3326  /* at some point we'll need to abstract this a little.  for now, if
3327     the protocol is UDP, we try to send some number of zero-length
3328     datagrams to allow the remote to get out of its loop without
3329     having to wait for the padded timer to expire. if it isn't UDP,
3330     we assume a reliable connection and can do the usual graceful
3331     shutdown thing */
3332
3333  /* this needs to be revisited for the netperf receiving case when
3334     the test is terminated by a Ctrl-C.  raj 2012-01-24 */
3335
3336  if (protocol != IPPROTO_UDP) {
3337    if (initiate)
3338      shutdown(data_socket, SHUT_WR);
3339
3340    /* we are expecting to get either a return of zero indicating
3341       connection close, or an error. of course, we *may* never
3342       receive anything from the remote which means we probably really
3343       aught to have a select here but until we are once bitten we
3344       will remain twice bold. */
3345    bytes_recvd = recv(data_socket,
3346		       buffer,
3347		       1,
3348		       0);
3349
3350    if (bytes_recvd != 0) {
3351      /* connection close, call close. we assume that the requisite
3352         number of bytes have been received */
3353      if (SOCKET_EINTR(bytes_recvd))
3354	{
3355	  /* We hit the end of a timed test. */
3356	  return -1;
3357	}
3358      return -3;
3359    }
3360  }
3361  else {
3362    int i;
3363    for (i = 0; i < 3; i++) {
3364      if (peer)
3365	bytes_recvd = sendto(data_socket,
3366			     buffer,
3367			     0,
3368			     0,
3369			     peer,
3370			     peerlen);
3371      else
3372	bytes_recvd = send(data_socket,
3373			   buffer,
3374			   0,
3375			   0);
3376      /* we only really care if the timer expired on us */
3377      if (SOCKET_EINTR(bytes_recvd)) {
3378	if (do_close)
3379	  close(data_socket);
3380	return -1;
3381      }
3382    }
3383  }
3384
3385  if (do_close)
3386    close(data_socket);
3387
3388  return 0;
3389}
3390
3391#ifdef HAVE_LINUX_TCP_H
3392static void
3393dump_tcp_info(struct tcp_info *tcp_info)
3394{
3395
3396  fprintf(stderr,
3397	  "tcpi_rto %d tcpi_ato %d tcpi_pmtu %d tcpi_rcv_ssthresh %d\n"
3398	  "tcpi_rtt %d tcpi_rttvar %d tcpi_snd_ssthresh %d tpci_snd_cwnd %d\n"
3399	  "tcpi_reordering %d tcpi_total_retrans %d\n",
3400	  tcp_info->tcpi_rto,
3401	  tcp_info->tcpi_ato,
3402	  tcp_info->tcpi_pmtu,
3403	  tcp_info->tcpi_rcv_ssthresh,
3404	  tcp_info->tcpi_rtt,
3405	  tcp_info->tcpi_rttvar,
3406	  tcp_info->tcpi_snd_ssthresh,
3407	  tcp_info->tcpi_snd_cwnd,
3408	  tcp_info->tcpi_reordering,
3409	  tcp_info->tcpi_total_retrans);
3410
3411  return;
3412}
3413
3414#endif
3415
3416static int
3417get_transport_retrans(SOCKET socket, int protocol) {
3418
3419#ifdef HAVE_LINUX_TCP_H
3420  struct tcp_info tcp_info;
3421
3422  int ret;
3423  netperf_socklen_t infosize;
3424
3425  if (protocol != IPPROTO_TCP)
3426    return -1;
3427
3428  infosize = sizeof(struct tcp_info);
3429
3430  if ((ret = getsockopt(socket,protocol,TCP_INFO,&tcp_info,&infosize)) < 0) {
3431    if (debug) {
3432      fprintf(where,
3433	      "%s: getsockopt errno %d %s\n",
3434	      __FUNCTION__,
3435	      errno,
3436	      strerror(errno));
3437      fflush(where);
3438    }
3439    return -1;
3440  }
3441  else {
3442
3443    /* we assume that if we have LINUX_TCP_H we also have getenv */
3444    if (debug > 1 || getenv("DUMP_TCP_INFO")) {
3445      dump_tcp_info(&tcp_info);
3446    }
3447    return tcp_info.tcpi_total_retrans;
3448  }
3449
3450
3451#else
3452  return -1;
3453#endif
3454}
3455
3456
3457static void
3458get_transport_info(SOCKET socket, int *mss, int protocol)
3459{
3460
3461  netperf_socklen_t sock_opt_len;
3462  int option;
3463  sock_opt_len = sizeof(netperf_socklen_t);
3464
3465  switch (protocol) {
3466#if defined(IPPROTO_TCP) && defined(TCP_MAXSEG)
3467  case IPPROTO_TCP:
3468    option = TCP_MAXSEG;
3469    break;
3470#endif
3471
3472#if defined(IPPROTO_SCTP) && defined(SCTP_MAXSEG)
3473  case IPPROTO_SCTP:
3474    option = SCTP_MAXSEG;
3475    break;
3476#endif
3477  default:
3478    *mss = -1;
3479    return;
3480  }
3481
3482  if (getsockopt(socket,
3483		 protocol,
3484		 option,
3485		 (char *)mss,
3486		 &sock_opt_len) == SOCKET_ERROR) {
3487    fprintf(where,
3488	    "%s: getsockopt: errno %d\n",
3489	    __FUNCTION__,
3490	    errno);
3491    fflush(where);
3492    *mss = -1;
3493  }
3494
3495}
3496
3497static void
3498get_transport_cong_control(SOCKET socket, int protocol, char cong_control[], int len)
3499{
3500#ifdef TCP_CONGESTION
3501  int my_len = len;
3502  if (protocol != IPPROTO_TCP) {
3503    strncpy(cong_control,"TCP Only",len);
3504  }
3505  else if (getsockopt(socket,
3506		      protocol, TCP_CONGESTION, cong_control, &my_len) ==
3507	   SOCKET_ERROR) {
3508    snprintf(cong_control,len,"%d errno",errno);
3509  }
3510#else
3511  strncpy(cong_control,"Unavailable",len);
3512#endif
3513  cong_control[len-1] = '\0';
3514}
3515
3516static void
3517set_transport_cong_control(SOCKET socket, int protocol, char cong_control[], int len)
3518{
3519#ifdef TCP_CONGESTION
3520  if (protocol == IPPROTO_TCP) {
3521    /* if it fails, we'll pick that up via the subsequent "get" */
3522    setsockopt(socket, protocol, TCP_CONGESTION, cong_control, len);
3523  }
3524#endif
3525}
3526
3527static void
3528set_receive_timeout(SOCKET sock, int timeout)
3529{
3530#ifdef SO_RCVTIMEO
3531#ifndef WIN32
3532  struct timeval foo;
3533
3534  foo.tv_sec = timeout;
3535  foo.tv_usec = 0;
3536
3537  if (setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,&foo,sizeof(foo)) < 0) {
3538    if (debug) {
3539      fprintf(where,"Note - attempt to set a receive timeout on the data socket failed with errno %d (%s)\n",
3540	      errno,
3541	      strerror(errno));
3542      fflush(where);
3543    }
3544  }
3545#endif
3546#endif
3547}
3548
3549static SOCKET
3550omni_create_data_socket(struct addrinfo *res)
3551{
3552  SOCKET temp_socket;
3553
3554  temp_socket = create_data_socket(res);
3555
3556  if (temp_socket != SOCKET_ERROR) {
3557    if (local_cong_control_req[0] != '\0') {
3558      set_transport_cong_control(temp_socket,
3559				 res->ai_protocol,
3560				 local_cong_control_req,
3561				 sizeof(local_cong_control_req));
3562    }
3563
3564    if ((res->ai_protocol == IPPROTO_UDP) &&
3565	(receive_timeout != -1)) {
3566      set_receive_timeout(temp_socket, receive_timeout);
3567    }
3568
3569    if (socket_debug) {
3570      int one = 1;
3571      setsockopt(temp_socket,
3572		 SOL_SOCKET,
3573		 SO_DEBUG,
3574		 &one,
3575		 sizeof(one));
3576    }
3577  }
3578  return temp_socket;
3579}
3580/* choosing the default send size is a trifle more complicated than it
3581   used to be as we have to account for different protocol limits */
3582
3583#define UDP_LENGTH_MAX (0xFFFF - 28)
3584
3585static int
3586choose_send_size(int lss, int protocol) {
3587
3588  int send_size;
3589
3590  if (lss > 0) {
3591    send_size = lss_size;
3592
3593    /* we will assume that everyone has IPPROTO_UDP and thus avoid an
3594       issue with Windows using an enum */
3595    if ((protocol == IPPROTO_UDP) && (send_size > UDP_LENGTH_MAX))
3596      send_size = UDP_LENGTH_MAX;
3597
3598  }
3599  else {
3600    send_size = 4096;
3601  }
3602  return send_size;
3603}
3604
3605/* brain dead simple way to get netperf to emit a uuid. sadly, by this
3606   point we will have already established the control connection but
3607   those are the breaks. we do _NOT_ include a trailing newline
3608   because we want to be able to use this in a script */
3609
3610void
3611print_uuid(char remote_host[])
3612{
3613  printf("%s",test_uuid);
3614}
3615#if defined(__linux)
3616/*
3617 * Linux has this odd behavior where if the socket buffers are larger
3618 * than a device's txqueuelen, the kernel will silently drop transmits
3619 * which would not fit into the tx queue, and not pass an ENOBUFS
3620 * error back to the application.  As a result, a UDP stream test can
3621 * report absurd transmit bandwidths (like 20Gb/s on a 1GbE NIC).
3622 * This behavior can be avoided if you request extended error
3623 * reporting on the socket.  This is done by setting the IP_RECVERR
3624 * socket option at the IP level.
3625 */
3626static void
3627enable_enobufs(int s)
3628{
3629  struct protoent *pr;
3630  int on = 1;
3631
3632  if ((pr = getprotobyname("ip")) == NULL) {
3633    fprintf(where, "%s failed: getprotobyname\n",__FUNCTION__);
3634    fflush(where);
3635    return;
3636  }
3637  if (setsockopt(s, pr->p_proto, IP_RECVERR, (char *)&on, sizeof(on)) < 0) {
3638    fprintf(where, "%s failed: setsockopt (errno %d)\n",__FUNCTION__,errno);
3639    fflush(where);
3640    return;
3641  }
3642}
3643#endif
3644
3645void
3646set_omni_request_flags(struct omni_request_struct *omni_request) {
3647
3648      /* we have no else clauses here because we previously set flags
3649	 to zero above raj 20090803 */
3650      if (rem_nodelay)
3651	omni_request->flags |= OMNI_NO_DELAY;
3652
3653      if (remote_use_sendfile)
3654	omni_request->flags |= OMNI_USE_SENDFILE;
3655
3656      if (connection_test)
3657	omni_request->flags |= OMNI_CONNECT_TEST;
3658
3659      if (remote_checksum_off)
3660	omni_request->flags |= OMNI_CHECKSUM_OFF;
3661
3662      if (remote_cpu_usage)
3663	omni_request->flags |= OMNI_MEASURE_CPU;
3664
3665      if (routing_allowed)
3666	omni_request->flags |= OMNI_ROUTING_ALLOWED;
3667
3668      if (desired_output_groups & OMNI_WANT_REM_IFNAME)
3669	omni_request->flags |= OMNI_WANT_IFNAME;
3670
3671      if (desired_output_groups & OMNI_WANT_REM_IFSLOT)
3672	omni_request->flags |= OMNI_WANT_IFSLOT;
3673
3674      if (desired_output_groups & OMNI_WANT_REM_IFIDS)
3675	omni_request->flags |= OMNI_WANT_IFIDS;
3676
3677      if (desired_output_groups & OMNI_WANT_REM_DRVINFO)
3678	omni_request->flags |= OMNI_WANT_DRVINFO;
3679
3680      if (desired_output_groups & OMNI_WANT_REM_CONG)
3681	omni_request->flags |= OMNI_WANT_REM_CONG;
3682
3683      if (use_fastopen)
3684	omni_request->flags |= OMNI_FASTOPEN;
3685
3686      if (want_use_pktinfo)
3687	omni_request->flags |= OMNI_USE_PKTINFO;
3688
3689      if (want_defer_accept)
3690	omni_request->flags |= OMNI_WANT_DEFER_ACCEPT;
3691
3692}
3693
3694
3695/* this code is intended to be "the two routines to run them all" for
3696   BSDish sockets.  it comes about as part of a desire to shrink the
3697   code footprint of netperf and to avoid having so many blessed
3698   routines to alter as time goes by.  the downside is there will be
3699   more "ifs" than there were before. raj 2008-01-07 */
3700
3701void
3702send_omni_inner(char remote_host[], unsigned int legacy_caller, char header_str[])
3703{
3704
3705  int ret,rret;
3706  int connected = 0;
3707  int timed_out = 0;
3708  int pad_time = 0;
3709
3710  struct ring_elt *send_ring;
3711  struct ring_elt *recv_ring;
3712
3713  struct sockaddr_storage remote_addr;
3714  struct sockaddr_storage my_addr;
3715  int                     remote_addr_len = sizeof(remote_addr);
3716  netperf_socklen_t       my_addr_len = sizeof(my_addr);
3717
3718  SOCKET	data_socket;
3719  int           need_socket;
3720
3721  uint32_t   temp_recvs;
3722  char  tmpfmt;
3723
3724  struct addrinfo *local_res;
3725  struct addrinfo *remote_res;
3726
3727  struct	omni_request_struct	*omni_request;
3728  struct	omni_response_struct	*omni_response;
3729  struct	omni_results_struct	*omni_result;
3730
3731#ifdef WANT_FIRST_BURST
3732  int requests_outstanding = 0;
3733#endif
3734
3735  omni_request =
3736    (struct omni_request_struct *)netperf_request.content.test_specific_data;
3737  omni_response =
3738    (struct omni_response_struct *)netperf_response.content.test_specific_data;
3739  omni_result =
3740    (struct omni_results_struct *)netperf_response.content.test_specific_data;
3741
3742
3743  if (keep_histogram) {
3744    if (first_burst_size > 0)
3745      time_hist = HIST_new_n(first_burst_size + 1);
3746    else
3747      time_hist = HIST_new_n(1);
3748  }
3749
3750  /* since we are now disconnected from the code that established the
3751     control socket, and since we want to be able to use different
3752     protocols and such, we are passed the name of the remote host and
3753     must turn that into the test specific addressing information. */
3754
3755  complete_addrinfos(&remote_res,
3756		     &local_res,
3757		     remote_host,
3758		     socket_type,
3759		     protocol,
3760		     0);
3761
3762  if ( print_headers ) {
3763    print_top_test_header(header_str,local_res,remote_res);
3764  }
3765
3766  /* initialize a few counters */
3767
3768  need_socket   = 1;
3769
3770  if (connection_test)
3771    pick_next_port_number(local_res,remote_res);
3772
3773
3774  /* If the user has requested cpu utilization measurements, we must
3775     calibrate the cpu(s). We will perform this task within the tests
3776     themselves. If the user has specified the cpu rate, then
3777     calibrate_local_cpu will return rather quickly as it will have
3778     nothing to do. If local_cpu_rate is zero, then we will go through
3779     all the "normal" calibration stuff and return the rate back.*/
3780
3781  if (local_cpu_usage) {
3782    local_cpu_rate = calibrate_local_cpu(local_cpu_rate);
3783  }
3784
3785  confidence_iteration = 1;
3786  init_stat();
3787
3788  send_ring = NULL;
3789  recv_ring = NULL;
3790
3791  /* you will keep running the test until you get it right! :) */
3792  while (((confidence < 0) && (confidence_iteration <= iteration_max)) ||
3793	 (confidence_iteration <= iteration_min)) {
3794
3795    trans_completed = 0;
3796    bytes_xferd	= 0.0;
3797    remote_bytes_xferd = 0.0;
3798    times_up 	= 0;
3799    bytes_sent = 0;
3800    bytes_received = 0;
3801    local_send_calls = 0;
3802    local_receive_calls = 0;
3803
3804    /* since we are tracking the number of outstanding requests for
3805       timestamping purposes, and since the previous iteration of
3806       using confidence intervals may not have completed all of them,
3807       we now need to forget about them or we will mistakenly fill our
3808       tracking array. raj 2011-03-14 */
3809    if (keep_histogram) {
3810      HIST_purge(time_hist);
3811    }
3812
3813#ifdef WANT_FIRST_BURST
3814    /* we have to remember to reset the number of transactions
3815       outstanding and the "congestion window for each new
3816       iteration. raj 2006-01-31. */
3817    requests_outstanding = 0;
3818#endif
3819
3820    /* if the command-line included requests to randomize the IP
3821       addresses, then honor it.  of course, this may not work all that
3822       well for some tests... raj 20101129 */
3823    if (local_mask_len)
3824      random_ip_address(local_res, local_mask_len);
3825    if (remote_mask_len)
3826      random_ip_address(remote_res, remote_mask_len);
3827
3828    data_socket = omni_create_data_socket(local_res);
3829
3830    if (data_socket == INVALID_SOCKET) {
3831      perror("netperf: send_omni: unable to create data socket");
3832      exit(1);
3833    }
3834#if defined(__linux)
3835    /* we really only need this for a UDP_STREAM test. we particularly
3836       do not want it for a CC or CRR test. raj 2012-08-06 */
3837    if ((protocol == IPPROTO_UDP) &&
3838	NETPERF_XMIT_ONLY(direction)) {
3839      enable_enobufs(data_socket);
3840    }
3841#endif
3842    need_socket = 0;
3843
3844    /* we need to consider if this is a request/response test, if we
3845       are receiving, if we are sending, etc, when setting-up our recv
3846       and send buffer rings. we should only need to do this once, and
3847       that would be when the relevant _ring variable is NULL. raj
3848       2008-01-18 */
3849    if (direction & NETPERF_XMIT) {
3850      if (is_multicast_addr(remote_res)) {
3851	set_multicast_ttl(data_socket);
3852      }
3853
3854      if (NULL == send_ring) {
3855	if (req_size > 0) {
3856	  /* request/response test */
3857	  if (send_width == 0) send_width = 1;
3858	  bytes_to_send = req_size;
3859	}
3860	else {
3861	  /* stream test */
3862	  if (send_size == 0) {
3863	    send_size = choose_send_size(lss_size,protocol);
3864	  }
3865	  if (send_width == 0)
3866	    send_width = (lss_size/send_size) + 1;
3867	  if (send_width == 1) send_width++;
3868	  bytes_to_send = send_size;
3869	}
3870
3871	send_ring = allocate_buffer_ring(send_width,
3872					 bytes_to_send,
3873					 local_send_align,
3874					 local_send_offset);
3875	if (debug) {
3876	  fprintf(where,
3877		  "%s: %d entry send_ring obtained...\n",
3878		  __FUNCTION__,
3879		  send_width);
3880	}
3881      }
3882    }
3883
3884    if (direction & NETPERF_RECV) {
3885      /* do we need to join a multicast group? */
3886      if (is_multicast_addr(local_res)) {
3887	join_multicast_addr(data_socket, local_res);
3888      }
3889
3890      /* do we need to allocate a recv_ring? */
3891      if (NULL == recv_ring) {
3892	if (rsp_size > 0) {
3893	  if (recv_width == 0) recv_width = 1;
3894	  bytes_to_recv = rsp_size;
3895	}
3896	else {
3897	  /* stream test */
3898	  if (recv_size == 0) {
3899	    if (lsr_size > 0) {
3900	      recv_size = lsr_size;
3901	    }
3902	    else {
3903	      recv_size = 4096;
3904	    }
3905	  }
3906	  if (recv_width == 0) {
3907	    recv_width = (lsr_size/recv_size) + 1;
3908	    if (recv_width == 1) recv_width++;
3909	  }
3910	  bytes_to_recv = recv_size;
3911	}
3912
3913	recv_ring = allocate_buffer_ring(recv_width,
3914					 bytes_to_recv,
3915					 local_recv_align,
3916					 local_recv_offset);
3917	if (debug) {
3918	  fprintf(where,
3919		  "%s: %d entry recv_ring obtained...\n",
3920		  __FUNCTION__,
3921		  recv_width);
3922	}
3923      }
3924    }
3925
3926    if (!no_control) {
3927
3928      /* Tell the remote end to do a listen or otherwise prepare for
3929	 what is to come. The server alters the socket paramters on the
3930	 other side at this point, hence the reason for all the values
3931	 being passed in the setup message. If the user did not specify
3932	 any of the parameters, they will be passed as values which will
3933	 indicate to the remote that no changes beyond the system's
3934	 default should be used. Alignment is the exception, it will
3935	 default to 8, which will probably be no alignment
3936	 alterations. */
3937
3938      netperf_request.content.request_type = DO_OMNI;
3939      omni_request->flags                  = 0;
3940      omni_request->send_buf_size	   = rss_size_req;
3941      omni_request->send_size              = remote_send_size_req;
3942      omni_request->send_alignment	   = remote_send_align;
3943      omni_request->send_offset	           = remote_send_offset;
3944      omni_request->send_width             = send_width;
3945      omni_request->request_size	   = req_size;
3946
3947      omni_request->recv_buf_size	   = rsr_size_req;
3948      omni_request->receive_size           = remote_recv_size_req;
3949      omni_request->recv_alignment	   = remote_recv_align;
3950      omni_request->recv_offset	           = remote_recv_offset;
3951      omni_request->recv_width             = recv_width;
3952      omni_request->response_size	   = rsp_size;
3953      omni_request->socket_prio            = remote_socket_prio;
3954      omni_request->socket_tos             = remote_socket_tos;
3955
3956      set_omni_request_flags(omni_request);
3957
3958      /* perhaps this should be made conditional on
3959	 remote_cong_control_req[0] not being NULL? */
3960      strncpy(omni_request->cong_control,
3961	      remote_cong_control_req,
3962	      sizeof(omni_request->cong_control));
3963      omni_request->cong_control[sizeof(omni_request->cong_control) - 1] =
3964	'\0';
3965
3966      if (want_keepalive)
3967	omni_request->flags |= OMNI_WANT_KEEPALIVE;
3968
3969      omni_request->cpu_rate	           = remote_cpu_rate;
3970      if (test_time)
3971	omni_request->test_length	   = test_time;
3972      else
3973	omni_request->test_length	   = test_trans * -1;
3974      omni_request->so_rcvavoid	           = rem_rcvavoid;
3975      omni_request->so_sndavoid	           = rem_sndavoid;
3976      omni_request->send_dirty_count       = rem_dirty_count;
3977      omni_request->recv_dirty_count       = rem_dirty_count;
3978      omni_request->recv_clean_count       = rem_clean_count;
3979
3980      omni_request->data_port              = atoi(remote_data_port);
3981      omni_request->ipfamily               = af_to_nf(remote_res->ai_family);
3982      omni_request->socket_type            = hst_to_nst(socket_type);
3983      omni_request->protocol               = protocol;
3984
3985      omni_request->interval_burst         = remote_interval_burst;
3986      omni_request->interval_usecs         = remote_interval_usecs;
3987
3988      omni_request->direction              = 0;
3989      /* yes, the sense here is correct - if we are transmitting, they
3990	 receive, if we are receiving, they are transmitting... */
3991      if (direction & NETPERF_XMIT)
3992	omni_request->direction |= NETPERF_RECV;
3993      if (direction & NETPERF_RECV)
3994	omni_request->direction |= NETPERF_XMIT;
3995
3996      /* some tests may require knowledge of our local addressing. such
3997	 tests will for the time being require that the user specify a
3998	 local IP/name so we can extract them from the data_socket. */
3999      getsockname(data_socket, (struct sockaddr *)&my_addr, &my_addr_len);
4000
4001      ret = get_sockaddr_family_addr_port(&my_addr,
4002					  nf_to_af(omni_request->ipfamily),
4003					  omni_request->netperf_ip,
4004					  &(omni_request->netperf_port));
4005      ret = get_sockaddr_family_addr_port((struct sockaddr_storage *)remote_res->ai_addr,
4006					  nf_to_af(omni_request->ipfamily),
4007					  omni_request->netserver_ip,
4008					  &(omni_request->data_port));
4009      /* if the user didn't explicitly set the remote data address we
4010	 don't want to pass along the one we picked implicitly, or a
4011	 netserver sitting behind a (BLETCH) NAT will be asked to try
4012	 to bind to the "public" IP. */
4013      if (!explicit_data_address) {
4014	omni_request->netserver_ip[0] = 0;
4015	omni_request->netserver_ip[1] = 0;
4016	omni_request->netserver_ip[2] = 0;
4017	omni_request->netserver_ip[3] = 0;
4018      }
4019      if (debug > 1) {
4020	fprintf(where,"netperf: %s: requesting OMNI test\n",__FUNCTION__);
4021      }
4022
4023      strncpy(omni_request->fill_file,
4024	      remote_fill_file,
4025	      sizeof(omni_request->fill_file));
4026
4027      send_request_n(OMNI_REQUEST_CONV_CUTOFF);
4028
4029
4030      /* the response from the remote should contain all the relevant
4031	 socket and other parameters we need to know for this test.
4032	 so, we can shove them back into the relevant variables here
4033	 and be on our way. */
4034
4035      recv_response_n(OMNI_RESPONSE_CONV_CUTOFF); /* brittle, but functional */
4036
4037      if (!netperf_response.content.serv_errno) {
4038	rsr_size	    = omni_response->recv_buf_size;
4039	remote_recv_size    = omni_response->receive_size;
4040	rss_size	    = omni_response->send_buf_size;
4041	remote_send_size    = omni_response->send_size;
4042	rem_nodelay         = omni_response->flags & OMNI_NO_DELAY;
4043	remote_use_sendfile = omni_response->flags & OMNI_USE_SENDFILE;
4044	remote_cpu_usage    = omni_response->flags & OMNI_MEASURE_CPU;
4045	remote_cpu_rate     = omni_response->cpu_rate;
4046	remote_send_width   = omni_response->send_width;
4047	remote_recv_width   = omni_response->recv_width;
4048	remote_socket_prio  = omni_response->socket_prio;
4049	remote_socket_tos   = omni_response->socket_tos;
4050
4051	/* make sure that port numbers are in network order because
4052	   recv_response will have put everything into host order */
4053	set_port_number(remote_res,
4054			(unsigned short)omni_response->data_port);
4055
4056	if (debug) {
4057	  fprintf(where,"remote listen done.\n");
4058	  fprintf(where,"remote port is %u\n",get_port_number(remote_res));
4059	  fflush(where);
4060	}
4061      }
4062      else {
4063	Set_errno(netperf_response.content.serv_errno);
4064	fprintf(where,
4065		"netperf: remote error %d",
4066		netperf_response.content.serv_errno);
4067	perror("");
4068	fflush(where);
4069	exit(-1);
4070      }
4071
4072    }
4073
4074#ifdef WANT_DEMO
4075    /* at some point we will have to be more clever about this, but
4076       for now we won't */
4077
4078    demo_rr_setup(100);
4079#endif
4080
4081    /* if we are not a connectionless protocol, we need to connect. at
4082       some point even if we are a connectionless protocol, we may
4083       still want to "connect" for convenience raj 2008-01-14 */
4084    need_to_connect = (protocol != IPPROTO_UDP) || local_connected;
4085
4086    /* possibly wait just a moment before actually starting - used
4087       mainly when one is doing many many many concurrent netperf
4088       tests */
4089    WAIT_BEFORE_DATA_TRAFFIC();
4090
4091    /* Set-up the test end conditions. For tests over a
4092       "reliable/connection-oriented" transport (eg TCP, SCTP, etc)
4093       this can be either time or byte/transaction count based.  for
4094       unreliable transport or connection tests it can only be time
4095       based.  having said that, we rely entirely on other code to
4096       enforce this before we even get here. raj 2008-01-08 */
4097
4098    /* enable a test_time of 0 to mean just keep running until
4099       something other than alarm() generates a signal. raj
4100       2012-02-01 */
4101    if ((test_time) || ((test_trans == 0) && (test_bytes == 0))) {
4102      /* The user wanted to end the test after a period of time.  if
4103	 we are a recv-only test, we need to protect ourself against
4104	 the remote going poof, but we want to make sure we don't
4105	 give-up before they finish, so we will add a PAD_TIME to the
4106	 timer.  if we are RR or XMIT, there should be no need for
4107	 padding */
4108      times_up = 0;
4109      units_remaining = 0;
4110      if ((!no_control) &&
4111	  (NETPERF_RECV_ONLY(direction)) &&
4112	  ((test_trans == 0) && (test_bytes == 0)))
4113	    pad_time = 0;
4114      start_timer(test_time + pad_time);
4115    }
4116    else {
4117      /* The tester wanted to send a number of bytes or exchange a
4118	 number of transactions. */
4119      if (NETPERF_IS_RR(direction))
4120	units_remaining = test_trans;
4121      else
4122	units_remaining = test_bytes;
4123      times_up = 1;
4124    }
4125
4126    /* grab the current time, and if necessary any starting information
4127       for the gathering of CPU utilization at this end. */
4128    cpu_start(local_cpu_usage);
4129
4130#if defined(WANT_INTERVALS)
4131    INTERVALS_INIT();
4132#endif /* WANT_INTERVALS */
4133
4134#ifdef WANT_DEMO
4135    if (demo_mode) {
4136      demo_first_timestamp();
4137    }
4138#endif
4139
4140    /* the "OR" here allows us to control test length by either
4141       byte/transaction count or by timer.  when the test is
4142       byte/transaction count based the time test will always evaluate
4143       false. when the test is controlled by time, the byte/transaction
4144       count will always evaluate to false.  when the test is finished
4145       the whole expression will go false and we will stop sending
4146       data. at least that is the plan :)  raj 2008-01-08 */
4147
4148    while ((!times_up) || (units_remaining > 0)) {
4149
4150      /* we need to be careful about when we snap a timestamp
4151	 depending on the test parameters. this one *should* cover
4152	 everything but the burst request/response test - famous last
4153	 words of course. raj 20110111 */
4154
4155      if (keep_histogram) {
4156	HIST_timestamp_start(time_hist);
4157      }
4158
4159
4160    again:
4161
4162      if (need_socket) {
4163	if (connection_test)
4164	  pick_next_port_number(local_res,remote_res);
4165
4166	data_socket = omni_create_data_socket(local_res);
4167
4168	if (data_socket == INVALID_SOCKET) {
4169	  perror("netperf: send_omni: unable to create data socket");
4170	  exit(1);
4171	}
4172	need_socket = 0;
4173#if defined(__linux)
4174	if ((protocol == IPPROTO_UDP) &&
4175	    (direction & NETPERF_XMIT)) {
4176	  enable_enobufs(data_socket);
4177	}
4178#endif
4179      }
4180
4181      /* only connect if and when we need to */
4182      if (need_to_connect && !use_fastopen) {
4183	/* assign to data_socket since connect_data_socket returns
4184	   SOCKET and not int thanks to Windows. */
4185	ret = connect_data_socket(data_socket,remote_res,dont_give_up);
4186	if (ret == 0) {
4187	  connected = 1;
4188	  need_to_connect = 0;
4189	}
4190	else if (ret == -1) {
4191	  times_up = 1;
4192	  timed_out = 1;
4193	  break;
4194	}
4195	else if ((ret == -2) && connection_test) {
4196	  /* transient error  on a connection test means go around and
4197	     try again with another local port number */
4198	  if (debug) {
4199	    fprintf(where,"transient! transient! torpedo in the water!\n");
4200	    fflush(where);
4201	  }
4202	  close(data_socket);
4203	  connected = 0;  /* probably redundant but what the heck... */
4204	  need_socket = 1;
4205	  need_to_connect = 1;
4206	  /* this will stuff the next local port number within bounds
4207	     into our local res, and then when the goto has us
4208	     allocating a new socket it will do the right thing with the
4209	     bind() call */
4210	  pick_next_port_number(local_res,remote_res);
4211	  /* yes Virginia, a goto.  perhaps one day we will rewrite
4212	     the code to avoid it but for now, a goto... raj */
4213	  goto again;
4214	}
4215	else {
4216	  /* either this was a hard failure (-3) or a soft failure on
4217	     something other than a connection test */
4218	  perror("netperf: send_omni: connect_data_socket failed");
4219	  exit(1);
4220	}
4221      }
4222
4223#ifdef WANT_FIRST_BURST
4224      /* Long ago and far away, on just about any *nix, one could
4225	 avoid having multiple requests bundled into the same TCP
4226	 segment simply by setting TCP_NODELAY and perhaps not trying
4227	 to have more outstanding at one time than our guesstimate as
4228	 to the TCP congestion window.  In that way one could use a
4229	 burst mode TCP_RR test as part of trying to measure maximum
4230	 packets per second (PPS) on a system or through a NIC (well,
4231	 assuming there weren't many retransmissions anyway) These
4232	 days with Linux the dominant *nix and with it having made it
4233	 virtually impossible to do any longer, it is no longer worth
4234	 it to try the application-layer backflips.  So, I am removing
4235	 them.  At some point we'll simply have to enhance this code
4236	 to deal with multiple connections at one time, each with just
4237	 the one transaction in flight for our PPS testing.  Multiple
4238	 netperfs, each with one connection and one transaction in
4239	 flight rapidly becomes a context-switching benchmark rather
4240	 than "networking".  raj 2015-04-20 */
4241
4242      while ((first_burst_size > 0) &&
4243	     (requests_outstanding < first_burst_size) &&
4244	     (NETPERF_IS_RR(direction)) &&
4245	     (!connection_test)) {
4246	if (debug > 1) {
4247	  fprintf(where,
4248		  "injecting, req_outstanding %d burst %d\n",
4249		  requests_outstanding,
4250		  first_burst_size);
4251	}
4252
4253	if ((ret = send_data(data_socket,
4254			     send_ring,
4255			     bytes_to_send,
4256			     (connected) ? NULL : remote_res->ai_addr,
4257			     remote_res->ai_addrlen,
4258			     protocol)) != bytes_to_send) {
4259	  /* in theory, we should never hit the end of the test in the
4260	     first burst.  however, in practice I have indeed seen
4261	     some ENOBUFS happen in some aggregate tests.  so we need
4262	     to be a bit more sophisticated in how we handle it. raj
4263	     20130516 */
4264	  if (ret != -2) {
4265	    perror("send_omni: initial burst data send error");
4266	    exit(-1);
4267	  }
4268	  failed_sends++;
4269	}
4270	else {
4271	  local_send_calls += 1;
4272	  requests_outstanding += 1;
4273	}
4274
4275	/* yes, it seems a trifle odd having this *after* the send()
4276	   just above, but really this is for the next send() or
4277	   recv() call below or in the iteration of this loop, and the
4278	   first HIST_timestamp_start() call at the top of the
4279	   outermost loop will be for the first send() call here in
4280	   the burst code.  clear ain't it?-) raj 20110111 */
4281
4282	if (keep_histogram) {
4283	  HIST_timestamp_start(time_hist);
4284	}
4285      }
4286
4287#endif /* WANT_FIRST_BURST */
4288
4289      /* if we should try to send something, then by all means, let us
4290	 try to send something. */
4291      if (direction & NETPERF_XMIT) {
4292
4293	ret = send_data(data_socket,
4294			send_ring,
4295			bytes_to_send,
4296			(connected) ? NULL : remote_res->ai_addr,
4297			/* if the destination above is NULL, this is ignored */
4298			remote_res->ai_addrlen,
4299			protocol);
4300	/* the order of these if's will seem a triffle strange, but they
4301	   are my best guess as to order of probabilty and/or importance
4302	   to the overhead raj 2008-01-09*/
4303	if (ret == bytes_to_send) {
4304	  /* if this is a send-only test controlled by byte count we
4305	     decrement units_remaining by the bytes sent */
4306	  if (!(direction & NETPERF_RECV) && (units_remaining > 0)) {
4307	    units_remaining -= ret;
4308	  }
4309	  bytes_sent += ret;
4310	  send_ring = send_ring->next;
4311	  local_send_calls++;
4312	}
4313	else if (ret == -2) {
4314	  /* what to do here -2 means a non-fatal error - probably
4315	     ENOBUFS and so our send didn't happen.  in the old code for
4316	     UDP_STREAM we would just continue in the while loop.  it
4317	     isn't clear that is what to do here, so we will simply
4318	     increment the failed_sends stat and fall-through. If this
4319	     is a UDP_STREAM style of test, the net effect should be the
4320	     same. if this is a UDP_RR with a really-big burst count, I
4321	     don't think we were checking for ENOBUFS there anyway and
4322	     so would have failed.  Here we can just let things
4323	     slide. */
4324	  failed_sends++;
4325	}
4326	else if (ret == 0) {
4327	  /* was this a zero-byte send? if it was, then ostensibly we
4328	     would hit the ret == bytes_to_send case which means we'd
4329	     never get here as we are using blocking semantics */
4330	  fprintf(where,"HOW DID I GET HERE?\n");
4331	  fflush(where);
4332	}
4333	else if (ret == -1) {
4334	  times_up = 1;
4335	  timed_out = 1;
4336	  break;
4337	}
4338	else {
4339	  perror("netperf: send_omni: send_data failed");
4340	  exit(1);
4341	}
4342
4343      }
4344
4345#ifdef WANT_FIRST_BURST
4346      /* it isn't clear we need to check the directions here.  the
4347	 increment should be cheaper than the conditional, and it
4348	 shouldn't hurt the other directions because they'll never
4349	 look at them. famous last words of raj 2008-01-25 */
4350      requests_outstanding += 1;
4351#endif
4352
4353#ifdef WIN32
4354      /* this is used so the timer thread can close the socket out
4355	from under us, which to date is the easiest/cleanest/least
4356	Windows-specific way I can find to force the winsock calls to
4357	return WSAEINTR with the test is over. anything that will run
4358	on 95 and NT and is closer to what netperf expects from Unix
4359	signals and such would be appreciated raj 1/96 */
4360      win_kludge_socket = data_socket;
4361#endif /* WIN32 */
4362
4363      if (direction & NETPERF_RECV) {
4364	rret = recv_data(data_socket,
4365			recv_ring,
4366			bytes_to_recv,
4367			(connected) ? NULL : (struct sockaddr *)&remote_addr,
4368			/* if remote_addr NULL this is ignored */
4369			&remote_addr_len,
4370			/* if XMIT also set this is RR so waitall */
4371			(direction & NETPERF_XMIT) ? NETPERF_WAITALL: 0,
4372			&temp_recvs);
4373	if (rret > 0) {
4374	  /* if this is a recv-only test controlled by byte count we
4375	     decrement the units_remaining by the bytes received */
4376	  if (!(direction & NETPERF_XMIT) && (units_remaining > 0)) {
4377	    units_remaining -= rret;
4378	  }
4379	  bytes_received += rret;
4380	  local_receive_calls += temp_recvs;
4381	}
4382	else if (rret == 0) {
4383	  /* is this the end of a test, just a zero-byte recv, or
4384	     something else? that is an exceedingly good question and
4385	     one for which I don't presently have a good answer, but
4386	     that won't stop me from guessing :) raj 2008-01-09 */
4387	  if (!((connection_test) || (null_message_ok))) {
4388	    /* if it is neither a connection_test nor null_message_ok it
4389	       must be the end of the test */
4390	    times_up = 1; /* ostensibly the signal handler did this */
4391	    break;
4392	  }
4393	  local_receive_calls += temp_recvs;
4394	}
4395	else if (rret == -1) {
4396	  /* test timed-out */
4397	  times_up = 1;
4398	  timed_out = 1;
4399	  break;
4400	}
4401	else if (rret == -2) {
4402	  /* we timed-out on a data receive.  this is only allowed for
4403	     a UDP_RR test.  we want to set things up so we start
4404	     ramping up again like we were at the beginning. if we
4405	     actually timeout it means that all has been lost.  or at
4406	     least we assume so */
4407	  if (debug) {
4408	    fprintf(where,"Timeout receiving resonse from remote\n");
4409	    fflush(where);
4410	  }
4411#ifdef WANT_FIRST_BURST
4412	  if (first_burst_size) {
4413	    requests_outstanding = 0;
4414	  }
4415#endif
4416	  if (keep_histogram) {
4417	    HIST_purge(time_hist);
4418	  }
4419#ifdef WANT_DEMO
4420	  /* "start over" on a demo interval. we will forget about
4421	  everything that happened in the demo interval up to the
4422	  timeout and begin fresh. */
4423	  demo_reset();
4424#endif /* WANT_DEMO */
4425
4426	  continue;
4427	}
4428	else {
4429	  /* anything else is bad */
4430	  perror("netperf: send_omni: recv_data failed");
4431	  exit(1);
4432	}
4433	recv_ring = recv_ring->next;
4434
4435#ifdef WANT_FIRST_BURST
4436	/* so, since we've gotten a response back, update the
4437	   bookkeeping accordingly.  there is one less request
4438	   outstanding and we can put one more out there than
4439	   before. */
4440	requests_outstanding -= 1;
4441#endif
4442
4443      }
4444
4445      /* if this is a connection test, we want to do some stuff about
4446	 connection close here in the test loop. raj 2008-01-08 */
4447      if (connection_test) {
4448
4449#ifdef __linux
4450	/* so, "Linux" with autotuning likes to alter the socket buffer
4451	   sizes over the life of the connection, but only does so when
4452	   one takes the defaults at time of socket creation.  if we
4453	   took those defaults, we should inquire as to what the values
4454	   ultimately became. raj 2008-01-15 */
4455	/* however annoying having to do this might be, it really
4456	   shouldn't be done over and over again. instead we will
4457	   assume it does not change, which is fine since we would
4458	   have only reported one of them anyway. raj 20100917 */
4459	if ((lsr_size_req < 0) && (-1 == lsr_size_end))
4460	  get_sock_buffer(data_socket, RECV_BUFFER, &lsr_size_end);
4461	else
4462	  lsr_size_end = lsr_size;
4463	if ((lss_size_req < 0) && (-1 == lss_size_end))
4464	  get_sock_buffer(data_socket, SEND_BUFFER, &lss_size_end);
4465	else
4466	  lss_size_end = lss_size;
4467#else
4468	lsr_size_end = lsr_size;
4469	lss_size_end = lss_size;
4470#endif
4471
4472	/* we will only make this call the one time - after the first
4473	   call, the value will be real or -1. if this is a connection
4474	   test we want to do this here because later we won't be
4475	   connected and the data may no longer be available. */
4476	if (transport_mss == -2)
4477	  get_transport_info(data_socket,
4478			     &transport_mss,
4479			     local_res->ai_protocol);
4480
4481
4482	ret = disconnect_data_socket(data_socket,
4483				     (no_control) ? 1 : 0,
4484				     1,
4485				     NULL,
4486				     0);
4487	if (ret == 0) {
4488	  /* we will need a new connection to be established next time
4489	     around the loop.  However, the next time around the loop
4490	     will already be picking the next port number */
4491	  need_to_connect = 1;
4492	  connected = 0;
4493	  need_socket = 1;
4494	}
4495	else if (ret == -1) {
4496	  times_up = 1;
4497	  timed_out = 1;
4498	  break;
4499	}
4500	else {
4501	  perror("netperf: send_omni: disconnect_data_socket failed");
4502	  exit(1);
4503	}
4504      }
4505
4506
4507      if (keep_histogram) {
4508	HIST_timestamp_stop_add(time_hist);
4509      }
4510
4511#ifdef WANT_DEMO
4512      if (NETPERF_IS_RR(direction)) {
4513	if (libfmt == 'x') {
4514	  demo_interval_tick(1);
4515	}
4516	else {
4517	  demo_interval_tick(req_size + rsp_size);
4518	}
4519      }
4520      else if (NETPERF_XMIT_ONLY(direction)) {
4521	demo_interval_tick(bytes_to_send);
4522      }
4523      else {
4524	demo_interval_tick(rret);
4525      }
4526#endif
4527
4528#if defined(WANT_INTERVALS)
4529      INTERVALS_WAIT();
4530#endif /* WANT_INTERVALS */
4531
4532
4533      /* was this a "transaction" test? */
4534      if (NETPERF_IS_RR(direction)) {
4535	trans_completed++;
4536	if (units_remaining) {
4537	  units_remaining--;
4538	}
4539      }
4540
4541
4542    }
4543
4544    /* we are now, ostensibly, at the end of this iteration */
4545
4546#if defined(WANT_DEMO)
4547    /* if we were in demo mode this will ensure one final interim
4548       result, which, naturally might be a bit early :) */
4549    demo_interval_final();
4550#endif
4551
4552    if (transport_mss == -2)
4553      get_transport_info(data_socket,
4554			 &transport_mss,
4555			 local_res->ai_protocol);
4556    local_transport_retrans = get_transport_retrans(data_socket,
4557						    local_res->ai_protocol);
4558
4559
4560    /* so, if we have/had a data connection, we will want to close it
4561       now, and this will be independent of whether there is a control
4562       connection. */
4563
4564    if (connected) {
4565
4566#ifdef __linux
4567      /* so, "Linux" with autotuning likes to alter the socket buffer
4568	 sizes over the life of the connection, but only does so when
4569	 one takes the defaults at time of socket creation.  if we took
4570	 those defaults, we should inquire as to what the values
4571	 ultimately became. raj 2008-01-15 */
4572      if (lsr_size_req < 0)
4573	get_sock_buffer(data_socket, RECV_BUFFER, &lsr_size_end);
4574      else
4575	lsr_size_end = lsr_size;
4576      if (lss_size_req < 0)
4577	get_sock_buffer(data_socket, SEND_BUFFER, &lss_size_end);
4578      else
4579	lss_size_end = lss_size;
4580#else
4581      lsr_size_end = lsr_size;
4582      lss_size_end = lss_size;
4583#endif
4584      if ((desired_output_groups & OMNI_WANT_LOC_CONG) &&
4585	  (local_cong_control[0] == '\0')) {
4586	get_transport_cong_control(data_socket,
4587				   local_res->ai_protocol,
4588				   local_cong_control,
4589				   sizeof(local_cong_control));
4590      }
4591
4592      /* CHECK PARMS HERE; */
4593      ret = disconnect_data_socket(data_socket,
4594				   1,
4595				   1,
4596				   NULL,
4597				   0);
4598      connected = 0;
4599      need_socket = 1;
4600
4601    }
4602    else {
4603      /* this is the UDP case at present */
4604      ret = disconnect_data_socket(data_socket,
4605				   1,
4606				   1,
4607				   remote_res->ai_addr,
4608				   remote_res->ai_addrlen);
4609      need_socket = 1;
4610      lsr_size_end = lsr_size;
4611      lss_size_end = lss_size;
4612    }
4613
4614    /* this call will always give us the elapsed time for the test, and
4615       will also store-away the necessaries for cpu utilization */
4616
4617    cpu_stop(local_cpu_usage,&elapsed_time);
4618
4619    /* if we timed-out, and had padded the timer, we need to subtract
4620       the pad_time from the elapsed time on the assumption that we
4621       were essentially idle for pad_time and just waiting for a timer
4622       to expire on something like a UDP test.  if we have not padded
4623       the timer, pad_time will be zero.  if we have not timed out
4624       then we want to make sure we stop the timer. */
4625    if (timed_out) {
4626      if (debug) {
4627	fprintf(where,"Adjusting elapsed_time by %d seconds\n",pad_time);
4628	fflush(where);
4629      }
4630      elapsed_time -= (float)pad_time;
4631    }
4632    else {
4633      stop_timer();
4634    }
4635
4636    if (!no_control) {
4637      /* Get the statistics from the remote end. The remote will have
4638	 calculated service demand and all those interesting things. If
4639	 it wasn't supposed to care, it will return obvious values. */
4640
4641      recv_response_n(OMNI_RESULTS_CONV_CUTOFF);
4642      if (!netperf_response.content.serv_errno) {
4643	if (debug)
4644	  fprintf(where,"remote results obtained\n");
4645	remote_cpu_method = format_cpu_method(omni_result->cpu_method);
4646	lib_num_rem_cpus = omni_result->num_cpus;
4647	lib_remote_cpu_stats.cpu_util = omni_result->cpu_util;
4648	lib_remote_cpu_stats.cpu_user = omni_result->cpu_percent_user;
4649	lib_remote_cpu_stats.cpu_system = omni_result->cpu_percent_system;
4650	lib_remote_cpu_stats.cpu_iowait = omni_result->cpu_percent_iowait;
4651	lib_remote_cpu_stats.cpu_irq = omni_result->cpu_percent_irq;
4652	lib_remote_cpu_stats.cpu_swintr = omni_result->cpu_percent_swintr;
4653	lib_remote_cpu_stats.peak_cpu_util = omni_result->peak_cpu_util;
4654	lib_remote_cpu_stats.peak_cpu_id = omni_result->peak_cpu_id;
4655	/* why?  because some stacks want to be clever and autotune their
4656	   socket buffer sizes, which means that if we accept the defaults,
4657	   the size we get from getsockopt() at the beginning of a
4658	   connection may not be what we would get at the end of the
4659	   connection... */
4660	rsr_size_end = omni_result->recv_buf_size;
4661	rss_size_end = omni_result->send_buf_size;
4662	remote_bytes_sent = (uint64_t)omni_result->bytes_sent_hi << 32;
4663	remote_bytes_sent += omni_result->bytes_sent_lo;
4664	remote_send_calls = omni_result->send_calls;
4665	remote_bytes_received = (uint64_t)omni_result->bytes_received_hi << 32;
4666	remote_bytes_received += omni_result->bytes_received_lo;
4667	remote_receive_calls = omni_result->recv_calls;
4668	remote_bytes_xferd = (double) remote_bytes_received +
4669	                              remote_bytes_sent;
4670	if (omni_result->recv_calls > 0)
4671	  remote_bytes_per_recv = (double) remote_bytes_received /
4672	    (double) omni_result->recv_calls;
4673	else
4674	  remote_bytes_per_recv = 0.0;
4675	if (omni_result->send_calls > 0)
4676	  remote_bytes_per_send = (double) remote_bytes_sent /
4677	    (double) omni_result->send_calls;
4678	else
4679	  remote_bytes_per_send = 0.0;
4680
4681	remote_transport_retrans = omni_result->transport_retrans;
4682	/* what was the congestion control? */
4683	if (desired_output_groups & OMNI_WANT_REM_CONG) {
4684	  strncpy(remote_cong_control,
4685		  omni_result->cong_control,
4686		  sizeof(remote_cong_control));
4687	  remote_cong_control[sizeof(remote_cong_control) - 1] = '\0';
4688	}
4689      }
4690      else {
4691	Set_errno(netperf_response.content.serv_errno);
4692	fprintf(where,
4693		"netperf: remote error %d",
4694		netperf_response.content.serv_errno);
4695	perror("");
4696	fflush(where);
4697
4698	exit(-1);
4699      }
4700    }
4701    else {
4702      /* when we are sending, in a no_control test, we have to
4703	 ass-u-me that everything we sent was received, otherwise, we
4704	 will report a transfer rate of zero. */
4705      remote_bytes_xferd = (double) bytes_sent;
4706    }
4707
4708    /* so, what was the end result? */
4709    local_cpu_method = format_cpu_method(cpu_method);
4710
4711    if (local_send_calls > 0)
4712      bytes_per_send = (double) bytes_sent / (double) local_send_calls;
4713    else bytes_per_send = 0.0;
4714
4715    if (local_receive_calls > 0)
4716      bytes_per_recv = (double) bytes_received / (double) local_receive_calls;
4717    else
4718      bytes_per_recv = 0.0;
4719
4720    bytes_xferd  = (double) bytes_sent + bytes_received;
4721
4722    /* if the output format is 'x' we know the test was
4723       request/response.  if the libfmt is something else, it could be
4724       xmit, recv or bidirectional. if we were the receiver then we
4725       can use our byte totals even if it is
4726       UDP/unreliable. otherwise, we use the remote totals - they
4727       should be the same if the protocol is reliable, and if it is
4728       unreliable then we want what was actually received */
4729    if ('x' == libfmt)
4730      /* it was a request/response test */
4731      thruput = calc_thruput((double)trans_completed);
4732    else if (NETPERF_RECV_ONLY(direction))
4733      thruput      = calc_thruput(bytes_xferd);
4734    else
4735      thruput = calc_thruput(remote_bytes_xferd);
4736
4737    if (NETPERF_IS_RR(direction)) {
4738      float rtt_elapsed_time = elapsed_time;
4739
4740#ifdef WANT_INTERVALS
4741      /* if the test was paced, we need to subtract the time we were
4742	 sitting paced from the time we use to calculate the average
4743	 rtt_latency. Of course, won't really know how long we were
4744	 sitting unless we bracket the sit with timing calls, which
4745	 will be additional overhead affecting CPU utilization.  but,
4746	 there is no such thing as a free lunch is there :) raj
4747	 20110121 */
4748      if (interval_burst) {
4749	rtt_elapsed_time -= (float)(interval_wait_microseconds / 1000000.0);
4750      }
4751#endif /* WANT_INTERVALS */
4752
4753      if (!connection_test) {
4754      /* calculate the round trip latency, using the transaction rate
4755	 whether or not the user was asking for thruput to be in 'x'
4756	 units please... however... a connection_test only ever has
4757	 one transaction in flight at one time */
4758      rtt_latency =
4759	(((double)1.0/(trans_completed/rtt_elapsed_time)) *
4760	 (double)1000000.0) *
4761	(double) (1 + ((first_burst_size > 0) ? first_burst_size : 0));
4762      }
4763      else {
4764	rtt_latency = ((double)1.0/(trans_completed/rtt_elapsed_time)) *
4765	  (double)1000000.0;
4766      }
4767      tmpfmt = libfmt;
4768      libfmt = 'x';
4769      transaction_rate = calc_thruput((double)trans_completed);
4770      libfmt = tmpfmt;
4771    }
4772
4773    /* ok, time to possibly calculate cpu util and/or service demand */
4774    if (local_cpu_usage) {
4775
4776      local_cpu_utilization = calc_cpu_util(elapsed_time);
4777
4778      /* we need to decide what to feed the service demand beast,
4779	 which will, ultimately, depend on what sort of test it is and
4780	 whether or not the user asked for something specific - as in
4781	 per KB even on a TCP_RR test if it is being (ab)used as a
4782	 bidirectional bulk-transfer test. raj 2008-01-14 */
4783      local_service_demand  =
4784	calc_service_demand_fmt(('x' == libfmt) ? (double)trans_completed: bytes_xferd,
4785				0.0,
4786				0.0,
4787				0);
4788    }
4789    else {
4790      local_cpu_utilization	= (float) -1.0;
4791      local_service_demand	= (float) -1.0;
4792    }
4793
4794    if (remote_cpu_usage) {
4795
4796      remote_cpu_utilization = omni_result->cpu_util;
4797
4798      remote_service_demand =
4799	calc_service_demand_fmt(('x' == libfmt) ? (double) trans_completed: bytes_xferd,
4800				0.0,
4801				remote_cpu_utilization,
4802				omni_result->num_cpus);
4803    }
4804    else {
4805      remote_cpu_utilization = (float) -1.0;
4806      remote_service_demand  = (float) -1.0;
4807    }
4808
4809    /* time to calculate our confidence */
4810    calculate_confidence(confidence_iteration,
4811			 elapsed_time,
4812			 thruput,
4813			 local_cpu_utilization,
4814			 remote_cpu_utilization,
4815			 local_service_demand,
4816			 remote_service_demand);
4817
4818    /* this this is the end of the confidence while loop? */
4819    confidence_iteration++;
4820  }
4821
4822  /* we end with confidence_iteration one larger than the number of
4823     iterations.  if we weren't doing confidence intervals this will
4824     still be reported as one */
4825  confidence_iteration--;
4826
4827#if defined(WANT_INTERVALS)
4828#ifdef WIN32
4829  stop_itimer();
4830#endif
4831#endif /* WANT_INTERVALS */
4832
4833/* at some point we may want to actually display some results :) */
4834
4835  retrieve_confident_values(&elapsed_time,
4836			    &thruput,
4837			    &local_cpu_utilization,
4838			    &remote_cpu_utilization,
4839			    &local_service_demand,
4840			    &remote_service_demand);
4841
4842  /* a kludge for omni printing because I don't know how to tell that
4843     something is a float vs a double in my_snprintf() given what it
4844     is passed and I'm not ready to force all the netlib.c stuff to
4845     use doubles rather than floats. help there would be
4846     appreciated. raj 2008-01-28 */
4847  elapsed_time_double = (double) elapsed_time;
4848  local_service_demand_double = (double)local_service_demand;
4849  remote_service_demand_double = (double)remote_service_demand;
4850
4851  if ('x' == libfmt) sd_str = "usec/Tran";
4852  else sd_str = "usec/KB";
4853
4854  if (iteration_max > 1) {
4855    result_confid_pct = get_result_confid();
4856    loc_cpu_confid_pct = get_loc_cpu_confid();
4857    rem_cpu_confid_pct = get_rem_cpu_confid();
4858    interval_pct = interval * 100.0;
4859  }
4860
4861  /* at some point we need to average these during a confidence
4862     interval run, and when we do do that, we need to make sure we
4863     restore the value of libfmt correctly */
4864  tmpfmt = libfmt;
4865  if ('x' == libfmt) {
4866    libfmt = 'm';
4867  }
4868  local_send_thruput = calc_thruput((double)bytes_sent);
4869  local_recv_thruput = calc_thruput((double)bytes_received);
4870  remote_send_thruput = calc_thruput((double)remote_bytes_sent);
4871  remote_recv_thruput = calc_thruput((double)remote_bytes_received);
4872
4873  libfmt = tmpfmt;
4874
4875  /* were we tracking possibly expensive statistics? */
4876  if (keep_statistics) {
4877    HIST_get_stats(time_hist,
4878		   &min_latency,
4879		   &max_latency,
4880		   &mean_latency,
4881		   &stddev_latency);
4882    p50_latency = HIST_get_percentile(time_hist, 0.50);
4883    p90_latency = HIST_get_percentile(time_hist, 0.90);
4884    p99_latency = HIST_get_percentile(time_hist, 0.99);
4885
4886  }
4887
4888  /* if we are running a legacy test we do not do the nifty new omni
4889     output stuff */
4890  if (!legacy) {
4891    print_omni();
4892  }
4893
4894#if defined(DEBUG_OMNI_OUTPUT)
4895 {
4896   /* just something quick to sanity check the output selectors. this
4897      should be gone for "production" :) */
4898   int i;
4899   print_omni_init();
4900   output_list[0][1] = OUTPUT_END;
4901   for (i = OUTPUT_NONE; i < NETPERF_OUTPUT_MAX; i++) {
4902     output_list[0][0] = i;
4903     print_omni_csv();
4904   }
4905 }
4906#endif
4907
4908  /* likely as not we are going to do something slightly different here */
4909  if ((verbosity > 1) && (!legacy)) {
4910
4911#ifdef WANT_HISTOGRAM
4912    fprintf(where,"\nHistogram of ");
4913    if (NETPERF_RECV_ONLY(direction))
4914      fprintf(where,"recv");
4915    if (NETPERF_XMIT_ONLY(direction))
4916      fprintf(where,"send");
4917    if (NETPERF_IS_RR(direction)) {
4918      if (connection_test) {
4919	if (NETPERF_CC(direction)) {
4920	  fprintf(where,"connect/close");
4921	}
4922	else {
4923	  fprintf(where,"connect/request/response/close");
4924	}
4925      }
4926      else {
4927	fprintf(where,"request/response");
4928      }
4929    }
4930    fprintf(where," times\n");
4931    HIST_report(time_hist);
4932    fflush(where);
4933#endif /* WANT_HISTOGRAM */
4934
4935  }
4936
4937}
4938
4939
4940void
4941send_omni(char remote_host[])
4942{
4943  char name_buf[32];
4944  snprintf(name_buf,sizeof(name_buf),"OMNI %s TEST",direction_str);
4945  name_buf[31] = '\0';
4946  send_omni_inner(remote_host, 0, name_buf);
4947}
4948
4949#if defined(WIN32)
4950#if !defined(InetNtop)
4951/* +*+ Why isn't this in the winsock headers yet? */
4952const char *
4953inet_ntop(int af, const void *src, char *dst, size_t size);
4954#endif
4955#endif
4956
4957static void
4958set_hostname_and_port_2(void *addr, char *hostname, char *portstr, int family, int port)
4959{
4960
4961  inet_ntop(family, addr, hostname, BUFSIZ);
4962
4963  sprintf(portstr, "%u", port);
4964
4965}
4966
4967
4968
4969/* the name is something of a misnomer since this test could send, or
4970   receive, or both, but it matches the historical netperf routine
4971   naming convention for what runs in the netserver context. */
4972void
4973recv_omni()
4974{
4975
4976  struct addrinfo *local_res;
4977  char local_name[BUFSIZ];
4978  char port_buffer[PORTBUFSIZE];
4979
4980  struct sockaddr_storage myaddr_in, peeraddr_in;
4981  int peeraddr_set = 0;
4982  SOCKET s_listen, data_socket;
4983  netperf_socklen_t 	addrlen;
4984
4985  struct ring_elt *send_ring;
4986  struct ring_elt *recv_ring;
4987
4988  int	timed_out = 0;
4989  int   pad_time = 0;
4990  int   need_to_connect = 0;
4991  int   need_to_accept;
4992  int   connected;
4993  int   ret;
4994  uint32_t   temp_recvs;
4995
4996  struct	omni_request_struct	*omni_request;
4997  struct	omni_response_struct	*omni_response;
4998  struct	omni_results_struct	*omni_results;
4999
5000  omni_request =
5001    (struct omni_request_struct *)netperf_request.content.test_specific_data;
5002  omni_response =
5003    (struct omni_response_struct *)netperf_response.content.test_specific_data;
5004  omni_results =
5005    (struct omni_results_struct *)netperf_response.content.test_specific_data;
5006
5007  if (debug) {
5008    fprintf(where,"netserver: %s: entered...\n",__FUNCTION__);
5009    fflush(where);
5010  }
5011
5012  /* netserver has no good way of knowing where the conversion cutoff
5013     point is, so we have to fix it after the fact */
5014  fixup_request_n(OMNI_REQUEST_CONV_CUTOFF);
5015
5016  /* thus fixed-up, we can extract the requested congestion control
5017     algorithm */
5018  strncpy(local_cong_control_req,
5019	  omni_request->cong_control,
5020	  sizeof(local_cong_control_req));
5021
5022  /* based on what we have been told by the remote netperf, we want to
5023     setup our endpoint for the "data connection" and let the remote
5024     netperf know the situation. */
5025
5026  if (debug) {
5027    fprintf(where,"%s: setting the response type...\n",__FUNCTION__);
5028    fflush(where);
5029  }
5030
5031  netperf_response.content.response_type = OMNI_RESPONSE;
5032
5033  if (debug) {
5034    fprintf(where,"%s: the response type is set...\n",__FUNCTION__);
5035    fflush(where);
5036  }
5037
5038  /* Grab a socket to listen on, and then listen on it. */
5039
5040  if (debug) {
5041    fprintf(where,"%s: grabbing a socket...\n",__FUNCTION__);
5042    fflush(where);
5043  }
5044
5045  /* create_data_socket expects to find some things in the global
5046     variables, so set the globals based on the values in the request.
5047     once the socket has been created, we will set the response values
5048     based on the updated value of those globals. raj 7/94 */
5049  lss_size_req    = omni_request->send_buf_size;
5050  lsr_size_req    = omni_request->recv_buf_size;
5051  loc_nodelay     = (omni_request->flags) & OMNI_NO_DELAY;
5052  loc_rcvavoid    = omni_request->so_rcvavoid;
5053  loc_sndavoid    = omni_request->so_sndavoid;
5054  routing_allowed = (omni_request->flags) & OMNI_ROUTING_ALLOWED;
5055  want_keepalive  = (omni_request->flags) & OMNI_WANT_KEEPALIVE;
5056  local_socket_prio = omni_request->socket_prio;
5057  local_socket_tos  = omni_request->socket_tos;
5058  want_defer_accept = omni_request->flags & OMNI_WANT_DEFER_ACCEPT;
5059
5060#ifdef WANT_INTERVALS
5061  interval_usecs = omni_request->interval_usecs;
5062  interval_wate  = interval_usecs / 1000;
5063  interval_burst = omni_request->interval_burst;
5064#else
5065  interval_usecs = 0;
5066  interval_wate  = 1;
5067  interval_burst = 0;
5068#endif
5069
5070  connection_test = omni_request->flags & OMNI_CONNECT_TEST;
5071#ifdef TCP_FASTOPEN
5072  use_fastopen = omni_request->flags & OMNI_FASTOPEN;
5073#endif
5074  direction       = omni_request->direction;
5075  use_pktinfo = (omni_request->flags) & OMNI_USE_PKTINFO;
5076
5077  /* let's be quite certain the fill file string is null terminated */
5078  omni_request->fill_file[sizeof(omni_request->fill_file) - 1] = '\0';
5079  strncpy(local_fill_file,
5080	  omni_request->fill_file,
5081	  sizeof(local_fill_file));
5082
5083  /* kludgy, because I have no way at present to say how many bytes
5084     needed to be swapped around for the request from which this is
5085     pulled, and it is probably all wrong for IPv6 :( */
5086  switch (nf_to_af(omni_request->ipfamily)) {
5087  case AF_INET6:
5088    /* yes indeed it is, do nothing, bz */
5089    break;
5090  case AF_INET:
5091  default:
5092    for (ret=0; ret < 4; ret++) {
5093      omni_request->netserver_ip[ret] = htonl(omni_request->netserver_ip[ret]);
5094      omni_request->netperf_ip[ret] = htonl(omni_request->netperf_ip[ret]);
5095    }
5096    break;
5097  }
5098
5099  set_hostname_and_port_2(omni_request->netserver_ip,
5100			  local_name,
5101			  port_buffer,
5102			  nf_to_af(omni_request->ipfamily),
5103			  omni_request->data_port);
5104
5105  local_res = complete_addrinfo(local_name,
5106				local_name,
5107				port_buffer,
5108				nf_to_af(omni_request->ipfamily),
5109				nst_to_hst(omni_request->socket_type),
5110				omni_request->protocol,
5111				0);
5112
5113  s_listen = omni_create_data_socket(local_res);
5114
5115  if (s_listen == INVALID_SOCKET) {
5116    netperf_response.content.serv_errno = errno;
5117    send_response();
5118    if (debug) {
5119      fprintf(where,"could not create data socket\n");
5120      fflush(where);
5121    }
5122    exit(-1);
5123  }
5124
5125  /* We now alter the message_ptr variables to be at the desired */
5126  /* alignments with the desired offsets. */
5127
5128  if (debug) {
5129    fprintf(where,
5130	    "recv_omni: requested recv alignment of %d offset %d\n"
5131	    "recv_omni: requested send alignment of %d offset %d\n",
5132	    omni_request->recv_alignment,
5133	    omni_request->recv_offset,
5134	    omni_request->send_alignment,
5135	    omni_request->send_offset);
5136    fflush(where);
5137  }
5138
5139  omni_response->send_size = omni_request->send_size;
5140  omni_response->send_width = omni_request->send_width;
5141  omni_response->socket_prio = local_socket_prio;
5142  omni_response->socket_tos = local_socket_tos;
5143
5144  if (omni_request->direction & NETPERF_XMIT) {
5145#ifdef fo
5146    /* do we need to set multicast ttl? */
5147    if (is_multicast_addr(remote_res)) {
5148      /* yes, s_listen - for a UDP test we will be copying it to
5149	 data_socket but that hasn't happened yet. raj 20100315 */
5150      set_multicast_ttl(s_listen);
5151    }
5152#endif
5153
5154    if (omni_request->response_size > 0) {
5155      /* request/response_test */
5156      bytes_to_send = omni_request->response_size;
5157      if (omni_request->send_width == 0) send_width = 1;
5158      else send_width = omni_request->send_width;
5159    }
5160    else {
5161      if (omni_request->send_size == -1) {
5162	bytes_to_send = choose_send_size(lss_size,omni_request->protocol);
5163      }
5164      else bytes_to_send = omni_request->send_size;
5165      /* set the send_width */
5166      if (omni_request->send_width == 0) {
5167	send_width = (lss_size/bytes_to_send) + 1;
5168	if (send_width == 1) send_width++;
5169      }
5170      else
5171	send_width = omni_request->send_width;
5172    }
5173    send_ring = allocate_buffer_ring(send_width,
5174				     bytes_to_send,
5175				     omni_request->send_alignment,
5176				     omni_request->send_offset);
5177
5178    omni_response->send_width = send_width;
5179    omni_response->send_size = bytes_to_send;
5180  }
5181
5182  omni_response->receive_size = omni_request->receive_size;
5183  omni_response->recv_width = omni_request->recv_width;
5184  if (omni_request->direction & NETPERF_RECV) {
5185
5186    /* do we need to join a multicast group? */
5187    if (is_multicast_addr(local_res)) {
5188      /* yes, s_listen - for a UDP test we will be copying it to
5189	 data_socket but that hasn't happened yet. raj 20100315 */
5190      join_multicast_addr(s_listen, local_res);
5191    }
5192
5193    if (omni_request->request_size > 0) {
5194      /* request/response test */
5195      bytes_to_recv = omni_request->request_size;
5196      if (omni_request->recv_width == 0) recv_width = 1;
5197      else recv_width = omni_request->recv_width;
5198    }
5199    else {
5200      if (omni_request->receive_size == -1) {
5201	if (lsr_size > 0) bytes_to_recv = lsr_size;
5202	else  bytes_to_recv = 4096;
5203      }
5204      else {
5205	bytes_to_recv = omni_request->receive_size;
5206      }
5207      /* set the recv_width */
5208      if (omni_request->recv_width == 0) {
5209	recv_width = (lsr_size/bytes_to_recv) + 1;
5210	if (recv_width == 1) recv_width++;
5211      }
5212      else
5213	recv_width = omni_request->recv_width;
5214    }
5215    recv_ring = allocate_buffer_ring(recv_width,
5216				     bytes_to_recv,
5217				     omni_request->recv_alignment,
5218				     omni_request->recv_offset);
5219
5220    omni_response->receive_size = bytes_to_recv;
5221    omni_response->recv_width = recv_width;
5222  }
5223
5224#ifdef WIN32
5225  /* The test timer can fire during operations on the listening socket,
5226     so to make the start_timer below work we have to move
5227     it to close s_listen while we are blocked on accept. */
5228  win_kludge_socket2 = s_listen;
5229#endif
5230
5231  need_to_accept = (omni_request->protocol != IPPROTO_UDP);
5232
5233  /* we need to hang a listen for everything that needs at least one
5234     accept. the age-old constant of 5 is probably OK for our purposes
5235     but does not necessarily represent best practice */
5236  if (need_to_accept) {
5237    int backlog = 5;
5238#ifdef TCP_FASTOPEN
5239    /* one of these days I will have to go find-out what the backlog
5240       is supposed to be here.  until then, I'll just set it to five
5241       like the listen() call does - it is classic, and was what was
5242       used in the online example I found */
5243    if (use_fastopen &&
5244	(setsockopt(s_listen,IPPROTO_TCP, TCP_FASTOPEN, &backlog, sizeof(backlog)) ==
5245	 SOCKET_ERROR)) {
5246      netperf_response.content.serv_errno = errno;
5247      close(s_listen);
5248      send_response();
5249      if (debug) {
5250	fprintf(where,"netperfserver: %s could not fastopen\n",__FUNCTION__);
5251	fflush(where);
5252      }
5253      exit(1);
5254    }
5255#endif /* TCP_FASTOPEN */
5256#ifdef TCP_DEFER_ACCEPT
5257    if (want_defer_accept &&
5258	(setsockopt(s_listen, IPPROTO_TCP, TCP_DEFER_ACCEPT, &backlog, sizeof(backlog)) == SOCKET_ERROR)) {
5259      netperf_response.content.serv_errno = errno;
5260      close(s_listen);
5261      send_response();
5262      if (debug) {
5263	fprintf(where,
5264		"netperfserver: %s could not defer accept\n",__FUNCTION__);
5265	fflush(where);
5266      }
5267      exit(1);
5268    }
5269#endif /* TCP_DEFER_ACCEPT */
5270    if (listen(s_listen, backlog) == SOCKET_ERROR) {
5271      netperf_response.content.serv_errno = errno;
5272      close(s_listen);
5273      send_response();
5274      if (debug) {
5275	fprintf(where,"netperfserver: %s could not listen\n",__FUNCTION__);
5276	fflush(where);
5277      }
5278      exit(1);
5279    }
5280  }
5281
5282  /* now get the port number assigned by the system  */
5283  addrlen = sizeof(myaddr_in);
5284  if (getsockname(s_listen,
5285		  (struct sockaddr *)&myaddr_in,
5286		  &addrlen) == SOCKET_ERROR){
5287    netperf_response.content.serv_errno = errno;
5288    close(s_listen);
5289    send_response();
5290    if (debug) {
5291      fprintf(where,"could not getsockname\n");
5292      fflush(where);
5293    }
5294    exit(-1);
5295  }
5296
5297  /* Now myaddr_in contains the port and the internet address this is
5298     returned to the sender also implicitly telling the sender that
5299     the socket buffer sizing has been done. likely as not, the IP
5300     address will be the wildcard - so we only really need to extract
5301     the port number. since send_response is going to call htonl on
5302     all the fields, we want to initially put the port number in there
5303     in host order. */
5304
5305  omni_response->data_port =
5306    (int) ntohs(((struct sockaddr_in *)&myaddr_in)->sin_port);
5307  if (debug) {
5308    fprintf(where,"telling the remote to call me at %d\n",
5309	    omni_response->data_port);
5310    fflush(where);
5311  }
5312  netperf_response.content.serv_errno   = 0;
5313
5314  /* But wait, there's more. If the initiator wanted cpu measurements, */
5315  /* then we must call the calibrate routine, which will return the max */
5316  /* rate back to the initiator. If the CPU was not to be measured, or */
5317  /* something went wrong with the calibration, we will return a 0.0 to */
5318  /* the initiator. */
5319
5320  omni_response->cpu_rate = (float)0.0; 	/* assume no cpu */
5321  omni_response->flags &= ~OMNI_MEASURE_CPU;
5322  if (omni_request->flags & OMNI_MEASURE_CPU) {
5323    omni_response->flags |= OMNI_MEASURE_CPU;
5324    omni_response->cpu_rate =
5325      calibrate_local_cpu(omni_request->cpu_rate);
5326  }
5327
5328  /* before we send the response back to the initiator, pull some of */
5329  /* the socket parms from the globals */
5330  omni_response->send_buf_size = lss_size;
5331  omni_response->recv_buf_size = lsr_size;
5332  if (loc_nodelay)
5333    omni_response->flags |= OMNI_NO_DELAY;
5334  else
5335    omni_response->flags &= ~OMNI_NO_DELAY;
5336
5337  omni_response->so_rcvavoid = loc_rcvavoid;
5338  omni_response->so_sndavoid = loc_sndavoid;
5339  omni_response->interval_usecs = interval_usecs;
5340  omni_response->interval_burst = interval_burst;
5341
5342  send_response_n(OMNI_RESPONSE_CONV_CUTOFF); /* brittle, but functional */
5343
5344  local_send_calls = 0;
5345  local_receive_calls = 0;
5346
5347  addrlen = sizeof(peeraddr_in);
5348  memset(&peeraddr_in,0,sizeof(peeraddr_in));
5349
5350  /* Now it's time to start receiving data on the connection. We will */
5351  /* first grab the apropriate counters and then start grabbing. */
5352
5353  cpu_start(omni_request->flags & OMNI_MEASURE_CPU);
5354
5355  /* if the test is timed, set a timer of suitable length.  if the
5356     test is by byte/transaction count, we don't need a timer - or
5357     rather we rely on the netperf to only ask us to do transaction
5358     counts over "reliable" protocols.  perhaps at some point we
5359     should add a check herebouts to verify that... */
5360
5361  if (omni_request->test_length >= 0) {
5362    times_up = 0;
5363    units_remaining = 0;
5364	test_time=omni_request->test_length;
5365    /* if we are the sender and only sending, then we don't need/want
5366       the padding, otherwise, we need the padding */
5367    if (!(NETPERF_XMIT_ONLY(omni_request->direction)) &&
5368	(omni_request->test_length > 0))
5369      pad_time = PAD_TIME;
5370    start_timer(omni_request->test_length + pad_time);
5371  }
5372  else {
5373    times_up = 1;
5374    units_remaining = omni_request->test_length * -1;
5375  }
5376
5377#if defined(WANT_INTERVALS)
5378  INTERVALS_INIT();
5379#endif /* WANT_INTERVALS */
5380
5381
5382  trans_completed = 0;
5383  bytes_sent = 0;
5384  bytes_received = 0;
5385  connected = 0;
5386
5387  while ((!times_up) || (units_remaining > 0)) {
5388
5389    if (need_to_accept) {
5390      /* accept a connection from the remote */
5391#ifdef WIN32
5392      /* The test timer will probably fire during this accept,
5393	 so to make the start_timer above work we have to move
5394	 it to close s_listen while we are blocked on accept. */
5395      win_kludge_socket = s_listen;
5396#endif
5397      if ((data_socket=accept(s_listen,
5398			      (struct sockaddr *)&peeraddr_in,
5399			      &addrlen)) == INVALID_SOCKET) {
5400	if (errno == EINTR) {
5401	  /* the timer popped */
5402	  times_up = 1; /* ostensibly the signal hander dealt with this?*/
5403	  timed_out = 1;
5404	  break;
5405	}
5406	netperf_response.content.serv_errno = errno;
5407	send_response();
5408	fprintf(where,"%s: accept: errno = %d\n",__FUNCTION__,errno);
5409	fflush(where);
5410	close(s_listen);
5411
5412	exit(-1);
5413      }
5414
5415      if (debug) {
5416	fprintf(where,"%s: accepted data connection.\n",__FUNCTION__);
5417	fflush(where);
5418      }
5419      need_to_accept = 0;
5420      connected = 1;
5421
5422#ifdef KLUDGE_SOCKET_OPTIONS
5423      /* this is for those systems which *INCORRECTLY* fail to pass
5424	 attributes across an accept() call. Including this goes
5425	 against my better judgement :( raj 11/95 */
5426
5427      kludge_socket_options(data_socket);
5428
5429#endif /* KLUDGE_SOCKET_OPTIONS */
5430
5431    }
5432    else {
5433      /* I wonder if duping would be better here? we also need to set
5434	 peeraddr_in so we can send to netperf if this isn't a
5435	 request/response test or if we are going to connect() the
5436	 socket, but we only need to do it once. */
5437      if ((omni_request->protocol == IPPROTO_UDP) &&
5438	  (!peeraddr_set)) {
5439	peeraddr_set = 1;
5440	data_socket = s_listen;
5441	set_sockaddr_family_addr_port(&peeraddr_in,
5442				      nf_to_af(omni_request->ipfamily),
5443				      omni_request->netperf_ip,
5444				      omni_request->netperf_port);
5445      }
5446    }
5447
5448#ifdef WIN32
5449  /* this is used so the timer thread can close the socket out from
5450     under us, which to date is the easiest/cleanest/least
5451     Windows-specific way I can find to force the winsock calls to
5452     return WSAEINTR with the test is over. anything that will run on
5453     95 and NT and is closer to what netperf expects from Unix signals
5454     and such would be appreciated raj 1/96 */
5455  win_kludge_socket = data_socket;
5456#endif /* WIN32 */
5457
5458    /* in recv_omni, we check recv first, and _then_ send, otherwise,
5459       a request/response test will be all messed-up :) and that then
5460       is why there are two routines to rule them all rather than just
5461       one :) */
5462    if ((omni_request->direction & NETPERF_RECV) &&
5463	((!times_up) || (units_remaining > 0))) {
5464      ret = recv_data(data_socket,
5465		      recv_ring,
5466		      bytes_to_recv,
5467		      (connected) ? NULL : (struct sockaddr *)&peeraddr_in,
5468		      &addrlen,
5469		      /* if XMIT also, then this is RR test so waitall */
5470		      (direction & NETPERF_XMIT) ? NETPERF_WAITALL: 0,
5471		      &temp_recvs);
5472      if (ret > 0) {
5473	/* if this is a recv-only test controlled by byte count we
5474	   decrement the units_remaining by the bytes received */
5475	if (!(direction & NETPERF_XMIT) && (units_remaining > 0)) {
5476	  units_remaining -= ret;
5477	}
5478	bytes_received += ret;
5479	local_receive_calls += temp_recvs;
5480      }
5481      else if (ret == 0) {
5482	/* is this the end of a test, just a zero-byte recv, or
5483	   something else? that is an exceedingly good question and
5484	   one for which I don't presently have a good answer, but
5485	   that won't stop me from guessing :) raj 2008-01-09 */
5486	if (!((connection_test) || (null_message_ok))) {
5487	  /* if it is neither a connection_test nor null_message_ok it
5488	     must be the end of the test */
5489	  times_up = 1;
5490	  break;
5491	}
5492	local_receive_calls += temp_recvs;
5493      }
5494      else if (ret == -1) {
5495	/* test timed-out */
5496	times_up = 1;
5497	timed_out = 1;
5498	break;
5499      }
5500      else {
5501	/* presently at least, -2 and -3 are equally bad on recv */
5502	/* we need a response message here for the control connection
5503	   before we exit! */
5504	netperf_response.content.serv_errno = errno;
5505	send_response();
5506	exit(-1);
5507      }
5508      recv_ring = recv_ring->next;
5509    }
5510
5511    /* if we should try to send something, then by all means, let us
5512       try to send something. */
5513    if ((omni_request->direction & NETPERF_XMIT) &&
5514	((!times_up) || (units_remaining > 0))) {
5515
5516      /* there used to be some code here looking sched_yield() until
5517	 there was no more queued, unsent data on the socket but
5518	 frankly, I've no idea what that was all about so I have
5519	 removed it. It may have been part of a kludge to try to avoid
5520	 coalescing requests and responses */
5521
5522      if (omni_request->protocol == IPPROTO_UDP && need_to_connect &&
5523          !connected) {
5524        if (connect(data_socket,
5525                    (struct sockaddr*)&peeraddr_in,
5526                    addrlen) == INVALID_SOCKET) {
5527	  netperf_response.content.serv_errno = errno;
5528	  send_response();
5529	  close(data_socket);
5530	  exit(-1);
5531        }
5532        connected = 1;
5533      }
5534
5535      ret = send_data(data_socket,
5536		      send_ring,
5537		      bytes_to_send,
5538		      (connected) ? NULL : (struct sockaddr *)&peeraddr_in,
5539		      addrlen,
5540		      omni_request->protocol);
5541
5542      /* the order of these if's will seem a triffle strange, but they
5543	 are my best guess as to order of probabilty and/or importance
5544	 to the overhead raj 2008-01-09*/
5545      if (ret == bytes_to_send) {
5546	/* if this is a send-only test controlled by byte count we
5547	   decrement units_remaining by the bytes sent */
5548	if (!(direction & NETPERF_RECV) && (units_remaining > 0)) {
5549	  units_remaining -= ret;
5550	}
5551	bytes_sent += ret;
5552	send_ring = send_ring->next;
5553	local_send_calls++;
5554      }
5555      else if (ret == -2) {
5556	/* what to do here -2 means a non-fatal error - probably
5557	   ENOBUFS and so our send didn't happen.  in the old code for
5558	   UDP_STREAM we would just continue in the while loop.  it
5559	   isn't clear that is what to do here, so we will simply
5560	   increment the failed_sends stat and fall-through. If this
5561	   is a UDP_STREAM style of test, the net effect should be the
5562	   same. if this is a UDP_RR with a really-big burst count, I
5563	   don't think we were checking for ENOBUFS there anyway and
5564	   so would have failed.  Here we can just let things
5565	   slide. */
5566	failed_sends++;
5567      }
5568      else if (ret == 0) {
5569	/* was this a zero-byte send? if it was, then ostensibly we
5570	   would hit the ret == bytes_to_send case which means we'd
5571	   never get here as we are using blocking semantics */
5572      }
5573      else if (ret == -1) {
5574	times_up = 1;
5575	timed_out = 1;
5576	break;
5577      }
5578      else {
5579	/* we need a response message back to netperf here before we
5580	   exit */
5581	/* NEED RESPONSE; */
5582	netperf_response.content.serv_errno = errno;
5583	send_response();
5584	exit(-1);
5585      }
5586
5587    }
5588
5589    if (connection_test) {
5590#ifdef __linux
5591      /* so, "Linux" with autotuning likes to alter the socket buffer
5592	 sizes over the life of the connection, but only does so when
5593	 one takes the defaults at time of socket creation.  if we
5594	 took those defaults, we should inquire as to what the values
5595	 ultimately became. raj 2008-01-15 */
5596      /* but as annoying as it is to have to make these calls, don't
5597	 penalize linux by calling them over and over again. instead
5598	 we will simply ass-u-me that it will become the same value
5599	 over and over again. raj 20100917 */
5600      if ((lsr_size_req < 0) && (-1 == lsr_size_end))
5601	get_sock_buffer(data_socket, RECV_BUFFER, &lsr_size_end);
5602      else
5603	lsr_size_end = lsr_size;
5604      if ((lss_size_req < 0) && (-1 == lss_size_end))
5605	get_sock_buffer(data_socket, SEND_BUFFER, &lss_size_end);
5606      else
5607	lss_size_end = lss_size;
5608#else
5609      lsr_size_end = lsr_size;
5610      lss_size_end = lss_size;
5611#endif
5612      ret = close_data_socket(data_socket,NULL,0,omni_request->protocol);
5613      if (ret == -1) {
5614	times_up = 1;
5615	timed_out = 1;
5616	break;
5617      }
5618      else if (ret < 0) {
5619	netperf_response.content.serv_errno = errno;
5620	send_response();
5621	perror("netperf: recv_omni: close_data_socket failed");
5622	fflush(where);
5623	exit(-1);
5624      }
5625      /* we will need a new connection to be established */
5626      need_to_accept = 1;
5627      connected = 0;
5628    }
5629
5630#if defined(WANT_INTERVALS)
5631    INTERVALS_WAIT();
5632#endif /* WANT_INTERVALS */
5633
5634    /* was this a "transaction" test? don't for get that a TCP_CC
5635       style test will have no xmit or recv :) so, we check for either
5636       both XMIT and RECV set, or neither XMIT nor RECV set */
5637    if (NETPERF_IS_RR(omni_request->direction)) {
5638      trans_completed++;
5639      if (units_remaining) {
5640	units_remaining--;
5641      }
5642    }
5643  }
5644
5645  /* The current iteration loop now exits due to timeout or unit count
5646     being  reached */
5647  stop_timer();
5648  cpu_stop(omni_request->flags & OMNI_MEASURE_CPU,&elapsed_time);
5649  close(s_listen);
5650
5651#if defined(WANT_INTERVALS)
5652#ifdef WIN32
5653  stop_itimer();
5654#endif
5655#endif /* WANT_INTERVALS */
5656
5657 if (timed_out) {
5658    /* we ended the test by time, which may have been PAD_TIME seconds
5659       longer than we wanted to run. so, we want to subtract pad_time
5660       from the elapsed_time. if we didn't pad the timer pad_time will
5661       be 0 so we can just subtract it anyway :) */
5662    if (debug) {
5663      fprintf(where,"Adjusting elapsed time by %d seconds\n",pad_time);
5664      fflush(where);
5665    }
5666    elapsed_time -= pad_time;
5667  }
5668
5669  remote_transport_retrans = get_transport_retrans(data_socket,
5670						   omni_request->protocol);
5671
5672  if (connected) {
5673#ifdef __linux
5674    /* so, "Linux" with autotuning likes to alter the socket buffer
5675       sizes over the life of the connection, but only does so when
5676       one takes the defaults at time of socket creation.  if we took
5677       those defaults, we should inquire as to what the values
5678       ultimately became. raj 2008-01-15 */
5679    if (lsr_size_req < 0)
5680      get_sock_buffer(data_socket, RECV_BUFFER, &lsr_size_end);
5681    else
5682      lsr_size_end = lsr_size;
5683    if (lss_size_req < 0)
5684      get_sock_buffer(data_socket, SEND_BUFFER, &lss_size_end);
5685    else
5686      lss_size_end = lss_size;
5687#else
5688    lsr_size_end = lsr_size;
5689    lss_size_end = lss_size;
5690#endif
5691    if (omni_request->flags & OMNI_WANT_REM_CONG) {
5692      get_transport_cong_control(data_socket,
5693				 local_res->ai_protocol,
5694				 omni_results->cong_control,
5695				 sizeof(omni_results->cong_control));
5696    }
5697    else {
5698      strncpy(omni_results->cong_control,"",sizeof(omni_results->cong_control));
5699    }
5700
5701
5702    close_data_socket(data_socket,NULL,0,omni_request->protocol);
5703  }
5704  else {
5705    close_data_socket(data_socket,(struct sockaddr *)&peeraddr_in,addrlen,omni_request->protocol);
5706    lsr_size_end = lsr_size;
5707    lss_size_end = lss_size;
5708  }
5709
5710  /* send the results to the sender  */
5711
5712  omni_results->send_calls      = (uint32_t) local_send_calls;
5713  omni_results->bytes_received_lo = bytes_received & 0x00000000FFFFFFFFULL;
5714  omni_results->bytes_received_hi = (bytes_received & 0xFFFFFFFF00000000ULL) >> 32;
5715  omni_results->recv_buf_size   = lsr_size_end;
5716  omni_results->recv_calls      = (uint32_t) local_receive_calls;
5717  omni_results->bytes_sent_lo   = bytes_sent & 0x00000000FFFFFFFFULL;
5718  omni_results->bytes_sent_hi   = (bytes_sent & 0xFFFFFFFF00000000ULL) >> 32;
5719  omni_results->send_buf_size   = lss_size_end;
5720  omni_results->trans_received	= (uint32_t) trans_completed;
5721  omni_results->elapsed_time	= elapsed_time;
5722  omni_results->transport_retrans = remote_transport_retrans;
5723  omni_results->cpu_method      = cpu_method;
5724  omni_results->num_cpus        = lib_num_loc_cpus;
5725  if (omni_request->flags & OMNI_MEASURE_CPU) {
5726    omni_results->cpu_util            = calc_cpu_util(elapsed_time);
5727    omni_results->cpu_percent_user    = lib_local_cpu_stats.cpu_user;
5728    omni_results->cpu_percent_system  = lib_local_cpu_stats.cpu_system;
5729    omni_results->cpu_percent_iowait  = lib_local_cpu_stats.cpu_iowait;
5730    omni_results->cpu_percent_irq     = lib_local_cpu_stats.cpu_irq;
5731    omni_results->cpu_percent_swintr  = lib_local_cpu_stats.cpu_swintr;
5732    omni_results->peak_cpu_util       = lib_local_cpu_stats.peak_cpu_util;
5733    omni_results->peak_cpu_id         = lib_local_cpu_stats.peak_cpu_id;
5734  }
5735
5736#if defined(WANT_INTERVALS)
5737#ifdef WIN32
5738  stop_itimer();
5739#endif
5740#endif /* WANT_INTERVALS */
5741
5742  if (debug) {
5743    fprintf(where,
5744	    "%s: test complete, sending results.\n",
5745	    __FUNCTION__);
5746    fflush(where);
5747  }
5748
5749  send_response_n(OMNI_RESULTS_CONV_CUTOFF);
5750
5751}
5752
5753
5754#ifdef WANT_MIGRATION
5755void
5756send_tcp_stream(char remote_host[])
5757{
5758
5759  char *tput_title = "\
5760Recv   Send    Send                          \n\
5761Socket Socket  Message  Elapsed              \n\
5762Size   Size    Size     Time     Throughput  \n\
5763bytes  bytes   bytes    secs.    %s/sec  \n\n";
5764
5765  char *tput_fmt_0 =
5766    "%7.2f %s\n";
5767
5768  char *tput_fmt_1 =
5769    "%6d %6d %6d    %-6.2f   %7.2f   %s\n";
5770
5771  char *cpu_title = "\
5772Recv   Send    Send                          Utilization       Service Demand\n\
5773Socket Socket  Message  Elapsed              Send     Recv     Send    Recv\n\
5774Size   Size    Size     Time     Throughput  local    remote   local   remote\n\
5775bytes  bytes   bytes    secs.    %-8.8s/s  %% %c      %% %c      us/KB   us/KB\n\n";
5776
5777  char *cpu_fmt_0 =
5778    "%6.3f %c %s\n";
5779
5780  char *cpu_fmt_1 =
5781    "%6d %6d %6d    %-6.2f     %7.2f   %-6.2f   %-6.2f   %-6.3f  %-6.3f %s\n";
5782
5783  char *ksink_fmt = "\n\
5784Alignment      Offset         %-8.8s %-8.8s    Sends   %-8.8s Recvs\n\
5785Local  Remote  Local  Remote  Xfered   Per                 Per\n\
5786Send   Recv    Send   Recv             Send (avg)          Recv (avg)\n\
5787%5d   %5d  %5d   %5d %6"PRId64"  %6.2f    %6"PRId64"   %6.2f %6"PRId64"\n";
5788
5789  char *ksink_fmt2 = "\n\
5790Maximum\n\
5791Segment\n\
5792Size (bytes)\n\
5793%6d\n";
5794
5795  send_omni_inner(remote_host, legacy, "MIGRATED TCP STREAM TEST");
5796
5797
5798  if (legacy) {
5799
5800    /* We are now ready to print all the information, but only if we
5801       are truly acting as a legacy test. If the user has specified
5802       zero-level verbosity, we will just print the local service
5803       demand, or the remote service demand. If the user has requested
5804       verbosity level 1, he will get the basic "streamperf"
5805       numbers. If the user has specified a verbosity of greater than
5806       1, we will display a veritable plethora of background
5807       information from outside of this block as it it not
5808       cpu_measurement specific...  */
5809
5810    if (confidence < 0) {
5811      /* we did not hit confidence, but were we asked to look for it? */
5812      if (iteration_max > 1) {
5813	display_confidence();
5814      }
5815    }
5816
5817    if (local_cpu_usage || remote_cpu_usage) {
5818
5819      switch (verbosity) {
5820      case 0:
5821	if (local_cpu_usage) {
5822	  fprintf(where,
5823		  cpu_fmt_0,
5824		  local_service_demand,
5825		  local_cpu_method,
5826		  ((print_headers) ||
5827		   (result_brand == NULL)) ? "" : result_brand);
5828	}
5829	else {
5830	  fprintf(where,
5831		  cpu_fmt_0,
5832		  remote_service_demand,
5833		  remote_cpu_method,
5834		  ((print_headers) ||
5835		   (result_brand == NULL)) ? "" : result_brand);
5836	}
5837	break;
5838      case 1:
5839      case 2:
5840	if (print_headers) {
5841	  fprintf(where,
5842		  cpu_title,
5843		  format_units(),
5844		  local_cpu_method,
5845		  remote_cpu_method);
5846	}
5847
5848	fprintf(where,
5849		cpu_fmt_1,		/* the format string */
5850		rsr_size,		/* remote recvbuf size */
5851		lss_size,		/* local sendbuf size */
5852		send_size,	        /* how large were the sends */
5853		elapsed_time,		/* how long was the test */
5854		thruput, 		/* what was the xfer rate */
5855		local_cpu_utilization,	/* local cpu */
5856		remote_cpu_utilization,	/* remote cpu */
5857		local_service_demand,	/* local service demand */
5858		remote_service_demand,	/* remote service demand */
5859		((print_headers) ||
5860		 (result_brand == NULL)) ? "" : result_brand);
5861	break;
5862      }
5863    }
5864    else {
5865      /* The tester did not wish to measure service demand. */
5866
5867      switch (verbosity) {
5868      case 0:
5869	fprintf(where,
5870		tput_fmt_0,
5871		thruput,
5872		((print_headers) ||
5873		 (result_brand == NULL)) ? "" : result_brand);
5874	break;
5875      case 1:
5876      case 2:
5877	if (print_headers) {
5878	  fprintf(where,tput_title,format_units());
5879	}
5880	fprintf(where,
5881		tput_fmt_1,		/* the format string */
5882		rsr_size, 		/* remote recvbuf size */
5883		lss_size, 		/* local sendbuf size */
5884		send_size,	        /* how large were the sends */
5885		elapsed_time, 		/* how long did it take */
5886		thruput,                /* how fast did it go */
5887		((print_headers) ||
5888		 (result_brand == NULL)) ? "" : result_brand);
5889	break;
5890      }
5891    }
5892
5893    /* it would be a good thing to include information about some of the */
5894    /* other parameters that may have been set for this test, but at the */
5895    /* moment, I do not wish to figure-out all the  formatting, so I will */
5896    /* just put this comment here to help remind me that it is something */
5897    /* that should be done at a later time. */
5898
5899    if (verbosity > 1) {
5900      /* The user wanted to know it all, so we will give it to him. */
5901      /* This information will include as much as we can find about */
5902      /* TCP statistics, the alignments of the sends and receives */
5903      /* and all that sort of rot... */
5904
5905      /* this stuff needs to be worked-out in the presence of confidence */
5906      /* intervals and multiple iterations of the test... raj 11/94 */
5907
5908      fprintf(where,
5909	      ksink_fmt,
5910	      "Bytes",
5911	      "Bytes",
5912	      "Bytes",
5913	      local_send_align,
5914	      remote_recv_align,
5915	      local_send_offset,
5916	      remote_recv_offset,
5917	      bytes_sent,
5918	      bytes_sent / (double)local_send_calls,
5919	      local_send_calls,
5920	      bytes_sent / (double)remote_receive_calls,
5921	      remote_receive_calls);
5922      fprintf(where,
5923	      ksink_fmt2,
5924	      transport_mss);
5925#ifdef WANT_HISTOGRAM
5926      fprintf(where,"\n\nHistogram of time spent in send() call.\n");
5927      HIST_report(time_hist);
5928#endif /* WANT_HISTOGRAM */
5929      fflush(where);
5930    }
5931
5932  }
5933}
5934
5935void
5936send_tcp_maerts(char remote_host[])
5937{
5938
5939  char *tput_title = "\
5940Recv   Send    Send                          \n\
5941Socket Socket  Message  Elapsed              \n\
5942Size   Size    Size     Time     Throughput  \n\
5943bytes  bytes   bytes    secs.    %s/sec  \n\n";
5944
5945  char *tput_fmt_0 =
5946    "%7.2f %s\n";
5947
5948  char *tput_fmt_1 =
5949    "%6d %6d %6d    %-6.2f   %7.2f   %s\n";
5950
5951  char *cpu_title = "\
5952Recv   Send    Send                          Utilization       Service Demand\n\
5953Socket Socket  Message  Elapsed              Recv     Send     Recv    Send\n\
5954Size   Size    Size     Time     Throughput  local    remote   local   remote\n\
5955bytes  bytes   bytes    secs.    %-8.8s/s  %% %c      %% %c      us/KB   us/KB\n\n";
5956
5957  char *cpu_fmt_0 =
5958    "%6.3f %c %s\n";
5959
5960  char *cpu_fmt_1 =
5961    "%6d %6d %6d    %-6.2f     %7.2f   %-6.2f   %-6.2f   %-6.3f  %-6.3f %s\n";
5962
5963  char *ksink_fmt = "\n\
5964Alignment      Offset         %-8.8s %-8.8s    Recvs   %-8.8s Sends\n\
5965Local  Remote  Local  Remote  Xfered   Per                 Per\n\
5966Recv   Send    Recv   Send             Recv (avg)          Send (avg)\n\
5967%5d   %5d  %5d   %5d %6"PRId64"  %6.2f    %6d   %6.2f %6d\n";
5968
5969  char *ksink_fmt2 = "\n\
5970Maximum\n\
5971Segment\n\
5972Size (bytes)\n\
5973%6d\n";
5974
5975  send_omni_inner(remote_host, legacy, "MIGRATED TCP MAERTS TEST");
5976
5977
5978  /* We are now ready to print all the information, but only if we are
5979     truly acting as a leacy test.  If the user has specified
5980     zero-level verbosity, we will just print the local service
5981     demand, or the remote service demand. If the user has requested
5982     verbosity level 1, he will get the basic "streamperf" numbers. If
5983     the user has specified a verbosity of greater than 1, we will
5984     display a veritable plethora of background information from
5985     outside of this block as it it not cpu_measurement
5986     specific...  */
5987
5988  if (legacy) {
5989
5990    if (confidence < 0) {
5991      /* we did not hit confidence, but were we asked to look for it? */
5992      if (iteration_max > 1) {
5993	display_confidence();
5994      }
5995    }
5996
5997    if (local_cpu_usage || remote_cpu_usage) {
5998
5999      switch (verbosity) {
6000      case 0:
6001	if (local_cpu_usage) {
6002	  fprintf(where,
6003		  cpu_fmt_0,
6004		  local_service_demand,
6005		  local_cpu_method,
6006		  ((print_headers) ||
6007		   (result_brand == NULL)) ? "" : result_brand);
6008	}
6009	else {
6010	  fprintf(where,
6011		  cpu_fmt_0,
6012		  remote_service_demand,
6013		  remote_cpu_method,
6014		  ((print_headers) ||
6015		   (result_brand == NULL)) ? "" : result_brand);
6016	}
6017	break;
6018      case 1:
6019      case 2:
6020	if (print_headers) {
6021	  fprintf(where,
6022		  cpu_title,
6023		  format_units(),
6024		  local_cpu_method,
6025		  remote_cpu_method);
6026	}
6027
6028	fprintf(where,
6029		cpu_fmt_1,		/* the format string */
6030		rsr_size,		/* remote recvbuf size */
6031		lss_size,		/* local sendbuf size */
6032		remote_send_size,	/* how large were the recvs */
6033		elapsed_time,		/* how long was the test */
6034		thruput, 		/* what was the xfer rate */
6035		local_cpu_utilization,	/* local cpu */
6036		remote_cpu_utilization,	/* remote cpu */
6037		local_service_demand,	/* local service demand */
6038		remote_service_demand,	/* remote service demand */
6039		((print_headers) ||
6040		 (result_brand == NULL)) ? "" : result_brand);
6041	break;
6042      }
6043    }
6044    else {
6045      /* The tester did not wish to measure service demand. */
6046
6047      switch (verbosity) {
6048      case 0:
6049	fprintf(where,
6050		tput_fmt_0,
6051		thruput,
6052		((print_headers) ||
6053		 (result_brand == NULL)) ? "" : result_brand);
6054	break;
6055      case 1:
6056      case 2:
6057	if (print_headers) {
6058	  fprintf(where,tput_title,format_units());
6059	}
6060	fprintf(where,
6061		tput_fmt_1,		/* the format string */
6062		lsr_size, 		/* local recvbuf size */
6063		rss_size, 		/* remot sendbuf size */
6064		remote_send_size,	/* how large were the recvs */
6065		elapsed_time, 		/* how long did it take */
6066		thruput,                /* how fast did it go */
6067		((print_headers) ||
6068		 (result_brand == NULL)) ? "" : result_brand);
6069	break;
6070      }
6071    }
6072
6073    /* it would be a good thing to include information about some of the */
6074    /* other parameters that may have been set for this test, but at the */
6075    /* moment, I do not wish to figure-out all the  formatting, so I will */
6076    /* just put this comment here to help remind me that it is something */
6077    /* that should be done at a later time. */
6078
6079    if (verbosity > 1) {
6080      /* The user wanted to know it all, so we will give it to him. */
6081      /* This information will include as much as we can find about */
6082      /* TCP statistics, the alignments of the sends and receives */
6083      /* and all that sort of rot... */
6084
6085      /* this stuff needs to be worked-out in the presence of confidence */
6086      /* intervals and multiple iterations of the test... raj 11/94 */
6087
6088      fprintf(where,
6089	      ksink_fmt,
6090	      "Bytes",
6091	      "Bytes",
6092	      "Bytes",
6093	      local_recv_align,
6094	      remote_recv_align,
6095	      local_recv_offset,
6096	      remote_recv_offset,
6097	      bytes_received,
6098	      bytes_received / (double)local_receive_calls,
6099	      local_receive_calls,
6100	      remote_bytes_sent / (double)remote_send_calls,
6101	      remote_send_calls);
6102      fprintf(where,
6103	      ksink_fmt2,
6104	      transport_mss);
6105
6106#ifdef WANT_HISTOGRAM
6107      fprintf(where,"\n\nHistogram of time spent in recv() call.\n");
6108      HIST_report(time_hist);
6109#endif /* WANT_HISTOGRAM */
6110      fflush(where);
6111    }
6112  }
6113}
6114
6115
6116void
6117send_tcp_rr(char remote_host[]) {
6118
6119  char *tput_title = "\
6120Local /Remote\n\
6121Socket Size   Request  Resp.   Elapsed  Trans.\n\
6122Send   Recv   Size     Size    Time     Rate         \n\
6123bytes  Bytes  bytes    bytes   secs.    per sec   \n\n";
6124
6125  char *tput_title_band = "\
6126Local /Remote\n\
6127Socket Size   Request  Resp.   Elapsed  \n\
6128Send   Recv   Size     Size    Time     Throughput \n\
6129bytes  Bytes  bytes    bytes   secs.    %s/sec   \n\n";
6130
6131  char *tput_fmt_0 =
6132    "%7.2f %s\n";
6133
6134  char *tput_fmt_1_line_1 = "\
6135%-6d %-6d %-6d   %-6d  %-6.2f   %7.2f   %s\n";
6136  char *tput_fmt_1_line_2 = "\
6137%-6d %-6d\n";
6138
6139  char *cpu_title = "\
6140Local /Remote\n\
6141Socket Size   Request Resp.  Elapsed Trans.   CPU    CPU    S.dem   S.dem\n\
6142Send   Recv   Size    Size   Time    Rate     local  remote local   remote\n\
6143bytes  bytes  bytes   bytes  secs.   per sec  %% %c    %% %c    us/Tr   us/Tr\n\n";
6144
6145  char *cpu_title_tput = "\
6146Local /Remote\n\
6147Socket Size   Request Resp.  Elapsed Tput     CPU    CPU    S.dem   S.dem\n\
6148Send   Recv   Size    Size   Time    %-8.8s local  remote local   remote\n\
6149bytes  bytes  bytes   bytes  secs.   per sec  %% %c    %% %c    us/KB   us/KB\n\n";
6150
6151  char *cpu_title_latency = "\
6152Local /Remote\n\
6153Socket Size   Request Resp.  Elapsed Latency  CPU    CPU    S.dem   S.dem\n\
6154Send   Recv   Size    Size   Time    usecs    local  remote local   remote\n\
6155bytes  bytes  bytes   bytes  secs.   per tran %% %c    %% %c    us/Tr   us/Tr\n\n";
6156
6157  char *cpu_fmt_0 =
6158    "%6.3f %c %s\n";
6159
6160  char *cpu_fmt_1_line_1 = "\
6161%-6d %-6d %-6d  %-6d %-6.2f  %-6.2f  %-6.2f %-6.2f %-6.3f  %-6.3f %s\n";
6162
6163  char *cpu_fmt_1_line_2 = "\
6164%-6d %-6d\n";
6165
6166  char *ksink_fmt = "\
6167Alignment      Offset         RoundTrip  Trans    Throughput\n\
6168Local  Remote  Local  Remote  Latency    Rate     %-8.8s/s\n\
6169Send   Recv    Send   Recv    usec/Tran  per sec  Outbound   Inbound\n\
6170%5d  %5d   %5d  %5d   %-6.3f   %-6.3f %-6.3f    %-6.3f\n";
6171
6172  send_omni_inner(remote_host, legacy, "MIGRATED TCP REQUEST/RESPONSE TEST");
6173
6174  if (legacy) {
6175    /* We are now ready to print all the information. If the user has
6176       specified zero-level verbosity, we will just print the local
6177       service demand, or the remote service demand. If the user has
6178       requested verbosity level 1, he will get the basic "streamperf"
6179       numbers. If the user has specified a verbosity of greater than 1,
6180       we will display a veritable plethora of background information
6181       from outside of this block as it it not cpu_measurement
6182       specific...  */
6183
6184    if (confidence < 0) {
6185      /* we did not hit confidence, but were we asked to look for it? */
6186      if (iteration_max > 1) {
6187	display_confidence();
6188      }
6189    }
6190
6191    if (local_cpu_usage || remote_cpu_usage) {
6192
6193      switch (verbosity) {
6194      case 0:
6195	if (local_cpu_usage) {
6196	  fprintf(where,
6197		  cpu_fmt_0,
6198		  local_service_demand,
6199		  local_cpu_method,
6200		  ((print_headers) ||
6201		   (result_brand == NULL)) ? "" : result_brand);
6202	}
6203	else {
6204	  fprintf(where,
6205		  cpu_fmt_0,
6206		  remote_service_demand,
6207		  remote_cpu_method,
6208		  ((print_headers) ||
6209		   (result_brand == NULL)) ? "" : result_brand);
6210	}
6211	break;
6212      case 1:
6213      case 2:
6214	if (print_headers) {
6215	  if ('x' == libfmt) {
6216	    fprintf(where,
6217		    cpu_title,
6218		    local_cpu_method,
6219		    remote_cpu_method);
6220	  }
6221	  else {
6222	    fprintf(where,
6223		    cpu_title_tput,
6224		    format_units(),
6225		    local_cpu_method,
6226		    remote_cpu_method);
6227	  }
6228	}
6229
6230	fprintf(where,
6231		cpu_fmt_1_line_1,		/* the format string */
6232		lss_size,		/* local sendbuf size */
6233		lsr_size,
6234		req_size,		/* how large were the requests */
6235		rsp_size,		/* guess */
6236		elapsed_time,		/* how long was the test */
6237		thruput,
6238		local_cpu_utilization,	/* local cpu */
6239		remote_cpu_utilization,	/* remote cpu */
6240		local_service_demand,	/* local service demand */
6241		remote_service_demand,	/* remote service demand */
6242		((print_headers) ||
6243		 (result_brand == NULL)) ? "" : result_brand);
6244	fprintf(where,
6245		cpu_fmt_1_line_2,
6246		rss_size,
6247		rsr_size);
6248	break;
6249      }
6250    }
6251    else {
6252      /* The tester did not wish to measure service demand. */
6253
6254      switch (verbosity) {
6255      case 0:
6256	fprintf(where,
6257		tput_fmt_0,
6258		thruput,
6259		((print_headers) ||
6260		 (result_brand == NULL)) ? "" : result_brand);
6261	break;
6262      case 1:
6263      case 2:
6264	if (print_headers) {
6265	  fprintf(where,
6266		  ('x' == libfmt) ? tput_title : tput_title_band,
6267		  format_units());
6268	}
6269
6270	fprintf(where,
6271		tput_fmt_1_line_1,	/* the format string */
6272		lss_size,
6273		lsr_size,
6274		req_size,		/* how large were the requests */
6275		rsp_size,		/* how large were the responses */
6276		elapsed_time, 		/* how long did it take */
6277		/* are we trans or do we need to convert to bytes then
6278		   bits? at this point, thruput is in our "confident"
6279		   transactions per second. we can convert to a
6280		   bidirectional bitrate by multiplying that by the sum
6281		   of the req_size and rsp_size.  we pass that to
6282		   calc_thruput_interval_omni with an elapsed time of
6283		   1.0 s to get it converted to [kmg]bits/s or
6284		   [KMG]Bytes/s */
6285		thruput,
6286		((print_headers) ||
6287		 (result_brand == NULL)) ? "" : result_brand);
6288	fprintf(where,
6289		tput_fmt_1_line_2,
6290		rss_size, 		/* remote recvbuf size */
6291		rsr_size);
6292
6293	break;
6294      }
6295    }
6296
6297    /* it would be a good thing to include information about some of the */
6298    /* other parameters that may have been set for this test, but at the */
6299    /* moment, I do not wish to figure-out all the  formatting, so I will */
6300    /* just put this comment here to help remind me that it is something */
6301    /* that should be done at a later time. */
6302
6303    /* how to handle the verbose information in the presence of */
6304    /* confidence intervals is yet to be determined... raj 11/94 */
6305    if (verbosity > 1) {
6306      /* The user wanted to know it all, so we will give it to him. */
6307      /* This information will include as much as we can find about */
6308      /* TCP statistics, the alignments of the sends and receives */
6309      /* and all that sort of rot... */
6310
6311      /* normally, you might think that if we were messing about with
6312	 the value of libfmt we would need to put it back again, but
6313	 since this is basically the last thing we are going to do with
6314	 it, it does not matter.  so there :) raj 2007-06-08 */
6315      /* if the user was asking for transactions, then we report
6316	 megabits per second for the unidirectional throughput,
6317	 otherwise we use the desired units. */
6318      if ('x' == libfmt) {
6319	libfmt = 'm';
6320      }
6321
6322      fprintf(where,
6323	      ksink_fmt,
6324	      format_units(),
6325	      local_send_align,
6326	      remote_recv_offset,
6327	      local_send_offset,
6328	      remote_recv_offset,
6329	      /* if the user has enable burst mode, we have to remember
6330		 to account for that in the number of transactions
6331		 outstanding at any one time. otherwise we will
6332		 underreport the latency of individual
6333		 transactions. learned from saf by raj 2007-06-08  */
6334	      (((double)1.0/transaction_rate)*(double)1000000.0) *
6335	      (double) (1 + ((first_burst_size > 0) ? first_burst_size : 0)),
6336	      transaction_rate,
6337	      calc_thruput_interval_omni(transaction_rate * (double)req_size,
6338					 1.0),
6339	      calc_thruput_interval_omni(transaction_rate * (double)rsp_size,
6340					 1.0));
6341
6342#ifdef WANT_HISTOGRAM
6343      fprintf(where,"\nHistogram of request/response times\n");
6344      HIST_report(time_hist);
6345#endif /* WANT_HISTOGRAM */
6346      fflush(where);
6347    }
6348  }
6349}
6350
6351
6352void
6353send_tcp_conn_rr(char remote_host[])
6354{
6355
6356  char *tput_title = "\
6357Local /Remote\n\
6358Socket Size   Request  Resp.   Elapsed  Trans.\n\
6359Send   Recv   Size     Size    Time     Rate         \n\
6360bytes  Bytes  bytes    bytes   secs.    per sec   \n\n";
6361
6362  char *tput_fmt_0 =
6363    "%7.2f\n";
6364
6365  char *tput_fmt_1_line_1 = "\
6366%-6d %-6d %-6d   %-6d  %-6.2f   %7.2f   \n";
6367  char *tput_fmt_1_line_2 = "\
6368%-6d %-6d\n";
6369
6370  char *cpu_title = "\
6371Local /Remote\n\
6372Socket Size   Request Resp.  Elapsed Trans.   CPU    CPU    S.dem   S.dem\n\
6373Send   Recv   Size    Size   Time    Rate     local  remote local   remote\n\
6374bytes  bytes  bytes   bytes  secs.   per sec  %%      %%      us/Tr   us/Tr\n\n";
6375
6376  char *cpu_fmt_0 =
6377    "%6.3f\n";
6378
6379  char *cpu_fmt_1_line_1 = "\
6380%-6d %-6d %-6d  %-6d %-6.2f  %-6.2f   %-6.2f %-6.2f %-6.3f  %-6.3f\n";
6381
6382  char *cpu_fmt_1_line_2 = "\
6383%-6d %-6d\n";
6384
6385  char *ksink_fmt = "\n\
6386Alignment      Offset\n\
6387Local  Remote  Local  Remote\n\
6388Send   Recv    Send   Recv\n\
6389%5d  %5d   %5d  %5d\n";
6390
6391  send_omni_inner(remote_host,
6392		  legacy,
6393		  "MIGRATED TCP Connect/Request/Response TEST");
6394
6395  /* We are now ready to print all the information. If the user */
6396  /* has specified zero-level verbosity, we will just print the */
6397  /* local service demand, or the remote service demand. If the */
6398  /* user has requested verbosity level 1, he will get the basic */
6399  /* "streamperf" numbers. If the user has specified a verbosity */
6400  /* of greater than 1, we will display a veritable plethora of */
6401  /* background information from outside of this block as it it */
6402  /* not cpu_measurement specific...  */
6403
6404  if (legacy) {
6405    if (confidence < 0) {
6406      /* we did not hit confidence, but were we asked to look for it? */
6407      if (iteration_max > 1) {
6408	display_confidence();
6409      }
6410    }
6411
6412    if (local_cpu_usage || remote_cpu_usage) {
6413
6414      switch (verbosity) {
6415      case 0:
6416	if (local_cpu_usage) {
6417	  fprintf(where,
6418		  cpu_fmt_0,
6419		  local_service_demand,
6420		  local_cpu_method);
6421	}
6422	else {
6423	  fprintf(where,
6424		  cpu_fmt_0,
6425		  remote_service_demand,
6426		  remote_cpu_method);
6427	}
6428	break;
6429      case 1:
6430      case 2:
6431	if (print_headers) {
6432	  fprintf(where,
6433		  cpu_title,
6434		  local_cpu_method,
6435		  remote_cpu_method);
6436	}
6437
6438	fprintf(where,
6439		cpu_fmt_1_line_1,	/* the format string */
6440		lss_size,		/* local sendbuf size */
6441		lsr_size,
6442		req_size,		/* how large were the requests */
6443		rsp_size,		/* guess */
6444		elapsed_time,		/* how long was the test */
6445		thruput,
6446		local_cpu_utilization,	/* local cpu */
6447		remote_cpu_utilization,	/* remote cpu */
6448		local_service_demand,	/* local service demand */
6449		remote_service_demand);	/* remote service demand */
6450	fprintf(where,
6451		cpu_fmt_1_line_2,
6452		rss_size,
6453		rsr_size);
6454	break;
6455      }
6456    }
6457    else {
6458      /* The tester did not wish to measure service demand. */
6459
6460      switch (verbosity) {
6461      case 0:
6462	fprintf(where,
6463		tput_fmt_0,
6464		thruput);
6465	break;
6466      case 1:
6467      case 2:
6468	if (print_headers) {
6469	  fprintf(where,tput_title,format_units());
6470	}
6471
6472	fprintf(where,
6473		tput_fmt_1_line_1,	/* the format string */
6474		lss_size,
6475		lsr_size,
6476		req_size,		/* how large were the requests */
6477		rsp_size,		/* how large were the responses */
6478		elapsed_time, 		/* how long did it take */
6479		thruput);
6480	fprintf(where,
6481		tput_fmt_1_line_2,
6482		rss_size, 		/* remote recvbuf size */
6483		rsr_size);
6484
6485	break;
6486      }
6487    }
6488
6489    /* it would be a good thing to include information about some of the */
6490    /* other parameters that may have been set for this test, but at the */
6491    /* moment, I do not wish to figure-out all the  formatting, so I will */
6492    /* just put this comment here to help remind me that it is something */
6493    /* that should be done at a later time. */
6494
6495    /* how to handle the verbose information in the presence of */
6496    /* confidence intervals is yet to be determined... raj 11/94 */
6497    if (verbosity > 1) {
6498      /* The user wanted to know it all, so we will give it to him. */
6499      /* This information will include as much as we can find about */
6500      /* TCP statistics, the alignments of the sends and receives */
6501      /* and all that sort of rot... */
6502
6503      fprintf(where,
6504	      ksink_fmt,
6505	      local_send_align,
6506	      remote_recv_align,
6507	      local_send_offset,
6508	      remote_recv_offset);
6509
6510#ifdef WANT_HISTOGRAM
6511      fprintf(where,"\nHistogram of request/response times\n");
6512      HIST_report(time_hist);
6513#endif /* WANT_HISTOGRAM */
6514      fflush(where);
6515    }
6516  }
6517}
6518
6519void
6520send_udp_stream(char remote_host[])
6521{
6522  /**********************************************************************/
6523  /*									*/
6524  /*               	UDP Unidirectional Send Test                    */
6525  /*									*/
6526  /**********************************************************************/
6527
6528  char *tput_title = "\
6529Socket  Message  Elapsed      Messages                \n\
6530Size    Size     Time         Okay Errors   Throughput\n\
6531bytes   bytes    secs            #      #   %s/sec\n\n";
6532
6533  char *tput_fmt_0 =
6534    "%7.2f\n";
6535
6536  char *tput_fmt_1 = "\
6537%6d  %6d   %-7.2f   %7"PRIu64" %6d    %7.2f\n\
6538%6d           %-7.2f   %7"PRIu64"           %7.2f\n\n";
6539
6540
6541  char *cpu_title = "\
6542Socket  Message  Elapsed      Messages                   CPU      Service\n\
6543Size    Size     Time         Okay Errors   Throughput   Util     Demand\n\
6544bytes   bytes    secs            #      #   %s/sec %% %c%c     us/KB\n\n";
6545
6546  char *cpu_fmt_0 =
6547    "%6.2f %c\n";
6548
6549  char *cpu_fmt_1 = "\
6550%6d  %6d   %-7.2f   %7"PRIu64" %6d    %7.1f     %-6.2f   %-6.3f\n\
6551%6d           %-7.2f   %7"PRIu64"           %7.1f     %-6.2f   %-6.3f\n\n";
6552
6553
6554  send_omni_inner(remote_host, legacy, "MIGRATED UDP STREAM TEST");
6555
6556  if (legacy) {
6557    /* We are now ready to print all the information. If the user has
6558       specified zero-level verbosity, we will just print the local
6559       service demand, or the remote service demand. If the user has
6560       requested verbosity level 1, he will get the basic "streamperf"
6561       numbers. If the user has specified a verbosity of greater than
6562       1, we will display a veritable plethora of background
6563       information from outside of this block as it it not
6564       cpu_measurement specific...  */
6565
6566
6567    if (confidence < 0) {
6568      /* we did not hit confidence, but were we asked to look for it? */
6569      if (iteration_max > 1) {
6570	display_confidence();
6571      }
6572    }
6573
6574    if (local_cpu_usage || remote_cpu_usage) {
6575
6576      switch (verbosity) {
6577      case 0:
6578	if (local_cpu_usage) {
6579	  fprintf(where,
6580		  cpu_fmt_0,
6581		  local_service_demand,
6582		  local_cpu_method);
6583	}
6584	else {
6585	  fprintf(where,
6586		  cpu_fmt_0,
6587		  remote_service_demand,
6588		  local_cpu_method);
6589	}
6590	break;
6591      case 1:
6592      case 2:
6593	if (print_headers) {
6594	  fprintf(where,
6595		  cpu_title,
6596		  format_units(),
6597		  local_cpu_method,
6598		  remote_cpu_method);
6599	}
6600
6601	fprintf(where,
6602		cpu_fmt_1,		/* the format string */
6603		lss_size,		/* local sendbuf size */
6604		send_size,		/* how large were the sends */
6605		elapsed_time,		/* how long was the test */
6606		local_send_calls,
6607		failed_sends,
6608		local_send_thruput, 	/* what was the xfer rate */
6609		local_cpu_utilization,	/* local cpu */
6610		local_service_demand,	/* local service demand */
6611		rsr_size,
6612		elapsed_time,
6613		remote_receive_calls,
6614		remote_recv_thruput,
6615		remote_cpu_utilization,	/* remote cpu */
6616		remote_service_demand);	/* remote service demand */
6617	break;
6618      }
6619    }
6620    else {
6621      /* The tester did not wish to measure service demand. */
6622      switch (verbosity) {
6623      case 0:
6624	fprintf(where,
6625		tput_fmt_0,
6626		local_send_thruput);
6627	break;
6628      case 1:
6629      case 2:
6630	if (print_headers) {
6631	  fprintf(where,tput_title,format_units());
6632	}
6633	fprintf(where,
6634		tput_fmt_1,		/* the format string */
6635		lss_size, 		/* local sendbuf size */
6636		send_size,		/* how large were the sends */
6637		elapsed_time, 		/* how long did it take */
6638		local_send_calls,
6639		failed_sends,
6640		local_send_thruput,
6641		rsr_size, 		/* remote recvbuf size */
6642		elapsed_time,
6643		remote_receive_calls,
6644		remote_recv_thruput);
6645	break;
6646      }
6647    }
6648
6649#ifdef WANT_HISTOGRAM
6650    if (verbosity > 1) {
6651      fprintf(where,"\nHistogram of time spent in send() call\n");
6652      HIST_report(time_hist);
6653    }
6654#endif /* WANT_HISTOGRAM */
6655    fflush(where);
6656  }
6657}
6658
6659void
6660send_udp_rr(char remote_host[])
6661{
6662
6663  char *tput_title = "\
6664Local /Remote\n\
6665Socket Size   Request  Resp.   Elapsed  Trans.\n\
6666Send   Recv   Size     Size    Time     Rate         \n\
6667bytes  Bytes  bytes    bytes   secs.    per sec   \n\n";
6668
6669  char *tput_title_band = "\
6670Local /Remote\n\
6671Socket Size   Request  Resp.   Elapsed  \n\
6672Send   Recv   Size     Size    Time     Throughput \n\
6673bytes  Bytes  bytes    bytes   secs.    %s/sec   \n\n";
6674
6675  char *tput_fmt_0 =
6676    "%7.2f %s\n";
6677
6678  char *tput_fmt_1_line_1 = "\
6679%-6d %-6d %-6d   %-6d  %-6.2f   %7.2f   %s\n";
6680
6681  char *tput_fmt_1_line_2 = "\
6682%-6d %-6d\n";
6683
6684  char *cpu_title = "\
6685Local /Remote\n\
6686Socket Size   Request Resp.  Elapsed Trans.   CPU    CPU    S.dem   S.dem\n\
6687Send   Recv   Size    Size   Time    Rate     local  remote local   remote\n\
6688bytes  bytes  bytes   bytes  secs.   per sec  %% %c    %% %c    us/Tr   us/Tr\n\n";
6689
6690  char *cpu_title_tput = "\
6691Local /Remote\n\
6692Socket Size   Request Resp.  Elapsed Tput     CPU    CPU    S.dem   S.dem\n\
6693Send   Recv   Size    Size   Time    %-8.8s local  remote local   remote\n\
6694bytes  bytes  bytes   bytes  secs.   per sec  %% %c    %% %c    us/KB   us/KB\n\n";
6695
6696  char *cpu_fmt_0 =
6697    "%6.3f %c %s\n";
6698
6699  char *cpu_fmt_1_line_1 = "\
6700%-6d %-6d %-6d  %-6d %-6.2f  %-6.2f   %-6.2f %-6.2f %-6.3f  %-6.3f %s\n";
6701
6702  char *cpu_fmt_1_line_2 = "\
6703%-6d %-6d\n";
6704
6705  send_omni_inner(remote_host, legacy, "MIGRATED UDP REQUEST/RESPONSE TEST");
6706
6707  if (legacy) {
6708    /* We are now ready to print all the information. If the user has
6709       specified zero-level verbosity, we will just print the local
6710       service demand, or the remote service demand. If the user has
6711       requested verbosity level 1, he will get the basic "streamperf"
6712       numbers. If the user has specified a verbosity of greater than
6713       1, we will display a veritable plethora of background
6714       information from outside of this block as it it not
6715       cpu_measurement specific...  */
6716
6717    if (confidence < 0) {
6718      /* we did not hit confidence, but were we asked to look for it? */
6719      if (iteration_max > 1) {
6720	display_confidence();
6721      }
6722    }
6723
6724    if (local_cpu_usage || remote_cpu_usage) {
6725
6726      switch (verbosity) {
6727      case 0:
6728	if (local_cpu_usage) {
6729	  fprintf(where,
6730		  cpu_fmt_0,
6731		  local_service_demand,
6732		  local_cpu_method,
6733		  ((print_headers) ||
6734		   (result_brand == NULL)) ? "" : result_brand);
6735
6736	}
6737	else {
6738	  fprintf(where,
6739		  cpu_fmt_0,
6740		  remote_service_demand,
6741		  remote_cpu_method,
6742		  ((print_headers) ||
6743		   (result_brand == NULL)) ? "" : result_brand);
6744
6745	}
6746	break;
6747      case 1:
6748      case 2:
6749	if (print_headers) {
6750	  if ('x' == libfmt) {
6751	    fprintf(where,
6752		    cpu_title,
6753		    local_cpu_method,
6754		    remote_cpu_method);
6755	  }
6756	  else {
6757	    fprintf(where,
6758		    cpu_title_tput,
6759		    format_units(),
6760		    local_cpu_method,
6761		    remote_cpu_method);
6762	  }
6763	}
6764
6765	fprintf(where,
6766		cpu_fmt_1_line_1,		/* the format string */
6767		lss_size,		/* local sendbuf size */
6768		lsr_size,
6769		req_size,		/* how large were the requests */
6770		rsp_size,		/* guess */
6771		elapsed_time,		/* how long was the test */
6772		thruput,
6773		local_cpu_utilization,	/* local cpu */
6774		remote_cpu_utilization,	/* remote cpu */
6775		local_service_demand,	/* local service demand */
6776		remote_service_demand,	/* remote service demand */
6777		((print_headers) ||
6778		 (result_brand == NULL)) ? "" : result_brand);
6779	fprintf(where,
6780		cpu_fmt_1_line_2,
6781		rss_size,
6782		rsr_size);
6783	break;
6784      }
6785    }
6786    else {
6787      /* The tester did not wish to measure service demand. */
6788      switch (verbosity) {
6789      case 0:
6790	fprintf(where,
6791		tput_fmt_0,
6792		thruput,
6793		((print_headers) ||
6794		 (result_brand == NULL)) ? "" : result_brand);
6795	break;
6796      case 1:
6797      case 2:
6798	if (print_headers) {
6799	  fprintf(where,
6800		  ('x' == libfmt) ? tput_title : tput_title_band,
6801		  format_units());
6802	}
6803
6804	fprintf(where,
6805		tput_fmt_1_line_1,	/* the format string */
6806		lss_size,
6807		lsr_size,
6808		req_size,		/* how large were the requests */
6809		rsp_size,		/* how large were the responses */
6810		elapsed_time, 		/* how long did it take */
6811		thruput,
6812		((print_headers) ||
6813		 (result_brand == NULL)) ? "" : result_brand);
6814	fprintf(where,
6815		tput_fmt_1_line_2,
6816		rss_size, 		/* remote recvbuf size */
6817		rsr_size);
6818
6819	break;
6820      }
6821    }
6822
6823    /* it would be a good thing to include information about some of the */
6824    /* other parameters that may have been set for this test, but at the */
6825    /* moment, I do not wish to figure-out all the  formatting, so I will */
6826    /* just put this comment here to help remind me that it is something */
6827    /* that should be done at a later time. */
6828
6829    /* how to handle the verbose information in the presence of */
6830    /* confidence intervals is yet to be determined... raj 11/94 */
6831
6832    if (verbosity > 1) {
6833      /* The user wanted to know it all, so we will give it to him. */
6834      /* This information will include as much as we can find about */
6835      /* UDP statistics, the alignments of the sends and receives */
6836      /* and all that sort of rot... */
6837
6838#ifdef WANT_HISTOGRAM
6839      fprintf(where,"\nHistogram of request/reponse times.\n");
6840      HIST_report(time_hist);
6841#endif /* WANT_HISTOGRAM */
6842    }
6843    fflush(where);
6844  }
6845}
6846
6847
6848#endif /* WANT_MIGRATION */
6849
6850
6851/* using legacy test names will cause certain default settings to be
6852   made before we scan the test-specific arguments.  raj 2010-07-20 */
6853static void
6854set_omni_defaults_by_legacy_testname() {
6855
6856  /* the uber defaults are for a unidirectional test using TCP */
6857  protocol = IPPROTO_TCP;
6858  socket_type = SOCK_STREAM;
6859  connection_test = 0;
6860  req_size = rsp_size = -1;
6861  was_legacy = 1;
6862  legacy = 1;
6863  implicit_direction = 0;  /* do we allow certain options to
6864			      implicitly affect the test direction? */
6865  if (strcasecmp(test_name,"TCP_STREAM") == 0) {
6866    direction = NETPERF_XMIT;
6867  }
6868  else if (strcasecmp(test_name,"TCP_MAERTS") == 0) {
6869    direction = NETPERF_RECV;
6870  }
6871  else if (strcasecmp(test_name,"TCP_RR") == 0) {
6872    req_size = rsp_size = 1;
6873    direction = 0;
6874    direction |= NETPERF_XMIT;
6875    direction |= NETPERF_RECV;
6876  }
6877  else if (strcasecmp(test_name,"UDP_STREAM") == 0) {
6878     protocol = IPPROTO_UDP;
6879    socket_type = SOCK_DGRAM;
6880  }
6881  else if (strcasecmp(test_name,"UDP_RR") == 0) {
6882     protocol = IPPROTO_UDP;
6883    socket_type = SOCK_DGRAM;
6884    direction = 0;
6885    direction |= NETPERF_XMIT;
6886    direction |= NETPERF_RECV;
6887    req_size = rsp_size = 1;
6888  }
6889  else if (strcasecmp(test_name,"TCP_CC") == 0) {
6890    direction = 0;
6891    connection_test = 1;
6892  }
6893  else if (strcasecmp(test_name,"TCP_CRR") == 0) {
6894    direction = 0;
6895    direction |= NETPERF_XMIT;
6896    direction |= NETPERF_RECV;
6897    req_size = rsp_size = 1;
6898    connection_test = 1;
6899  }
6900  else if (strcasecmp(test_name,"omni") == 0) {
6901    /* there is not much to do here but clear the legacy flag */
6902    was_legacy = 0;
6903    legacy = 0;
6904    implicit_direction = 1;
6905  }
6906  socket_type_str = hst_to_str(socket_type);
6907}
6908
6909char omni_usage[] = "\n\
6910Usage: netperf [global options] -- [test options] \n\
6911\n\
6912OMNI and Migrated BSD Sockets Test Options:\n\
6913    -b number         Send number requests at start of _RR tests\n\
6914    -c                Explicitly declare this a connection test such as\n\
6915                      TCP_CRR or TCP_CC\n\
6916    -C                Set TCP_CORK when available\n\
6917    -d direction      Explicitly set test direction based on bitwise OR\n\
6918                      of 0x2 for transmit and 0x4 for receive. Default:\n\
6919                      based on test type\n\
6920    -D [L][,R]        Set TCP_NODELAY locally and/or remotely (TCP_*)\n\
6921    -h                Display this text\n\
6922    -H name[/mask],fam  Use name (or IP) and family as target of data connection\n\
6923                      A mask value will cause randomization of the IP used\n\
6924    -k [file]         Generate keyval output optionally based on file\n\
6925                      Use filename of '?' to get the list of choices\n\
6926    -K loc[,rem]      Set the local and/or remote congestion control\n\
6927                      algorithm to use on those platforms where it can\n\
6928                      be set.\n\
6929    -L name[/mask],fam  Use name (or IP) and family as source of data connection\n\
6930                      A mask value will cause randomization of the IP used\n\
6931    -m local,remote   Set the send size for _STREAM/_MAERTS tests\n\
6932    -M local,remote   Set the recv size for _STREAM/_MAERTS tests\n\
6933    -n                Use the connected socket for UDP locally\n\
6934    -N                Use the connected socket for UDP remotely\n\
6935    -o [file]         Generate CSV output optionally based on file\n\
6936                      Use filename of '?' to get the list of choices\n\
6937    -O [file]         Generate classic-style output based on file\n\
6938                      Use filename of '?' to get the list of choices\n\
6939    -p min[,max]      Set the min/max port numbers for TCP_CRR, TCP_TRR\n\
6940    -P local[,remote] Set the local/remote port for the data socket\n\
6941    -r req,[rsp]      Set request/response sizes (TCP_RR, UDP_RR)\n\
6942    -R 0/1            Allow routing of traffic on data connection.\n\
6943                      Default: 0 (off) for UDP_STREAM, 1 (on) otherwise\n\
6944    -s send[,recv]    Set local socket send/recv buffer sizes\n\
6945    -S send[,recv]    Set remote socket send/recv buffer sizes\n\
6946    -t type           Explicitly set socket type. Default is implicit\n\
6947                      based on other settings\n\
6948    -T protocol       Explicitly set data connection protocol. Default is\n\
6949                      implicit based on other settings\n\
6950    -u uuid           Use the supplied string as the UUID for this test.\n\
6951    -4                Use AF_INET (eg IPv4) on both ends of the data conn\n\
6952    -6                Use AF_INET6 (eg IPv6) on both ends of the data conn\n\
6953\n\
6954For those options taking two parms, at least one must be specified;\n\
6955specifying one value without a comma will set both parms to that\n\
6956value, specifying a value with a leading comma will set just the second\n\
6957parm, a value with a trailing comma will set just the first. To set\n\
6958each parm to unique values, specify both and separate them with a\n\
6959comma.\n";
6960
6961void
6962print_omni_usage()
6963{
6964
6965  fwrite(omni_usage, sizeof(char), strlen(omni_usage), stdout);
6966  exit(1);
6967
6968}
6969
6970
6971void
6972scan_omni_args(int argc, char *argv[])
6973
6974{
6975
6976#define OMNI_ARGS "aBb:cCd:De:FgG:hH:i:Ij:kK:l:L:m:M:nNoOp:P:r:R:s:S:t:T:u:UVw:W:46"
6977
6978  extern char	*optarg;	  /* pointer to option string	*/
6979
6980  int		c;
6981  int           have_uuid = 0;
6982  int           have_R_option = 0;
6983
6984  char
6985    arg1[BUFSIZ],  /* argument holders		*/
6986    arg2[BUFSIZ],
6987    arg3[BUFSIZ];
6988
6989  if (debug) {
6990    int i;
6991    printf("%s called with the following argument vector\n",
6992	   __FUNCTION__);
6993    for (i = 0; i< argc; i++) {
6994      printf("%s ",argv[i]);
6995    }
6996    printf("\n");
6997  }
6998
6999  /* double-check struct sizes */
7000  {
7001    const union netperf_request_struct * u = (const union netperf_request_struct *)0;
7002    if (debug) {
7003      fprintf(where, "sizeof(omni_request_struct)=%d/%d\n",
7004              (int)sizeof(struct omni_request_struct),
7005              (int)sizeof(u->content.test_specific_data));
7006      fprintf(where, "sizeof(omni_response_struct)=%d/%d\n",
7007              (int)sizeof(struct omni_response_struct),
7008              (int)sizeof(u->content.test_specific_data));
7009      fprintf(where, "sizeof(omni_results_struct)=%d/%d\n",
7010              (int)sizeof(struct omni_results_struct),
7011              (int)sizeof(u->content.test_specific_data));
7012    }
7013    assert(sizeof(struct omni_request_struct)
7014           <= sizeof(u->content.test_specific_data));
7015    assert(sizeof(struct omni_response_struct)
7016           <= sizeof(u->content.test_specific_data));
7017    assert(sizeof(struct omni_results_struct)
7018           <= sizeof(u->content.test_specific_data));
7019  }
7020
7021  strncpy(local_data_port,"0",sizeof(local_data_port));
7022  strncpy(remote_data_port,"0",sizeof(remote_data_port));
7023
7024  /* this will handle setting default settings based on test name */
7025  set_omni_defaults_by_legacy_testname();
7026
7027  /* Go through all the command line arguments and break them out. For
7028     those options that take two parms, specifying only the first will
7029     set both to that value. Specifying only the second will leave the
7030     first untouched. To change only the first, use the form "first,"
7031     (see the routine break_args.. */
7032
7033  while ((c= getopt(argc, argv, OMNI_ARGS)) != EOF) {
7034    switch (c) {
7035    case '?':
7036    case '4':
7037      remote_data_family = AF_INET;
7038      local_data_family = AF_INET;
7039      break;
7040    case '6':
7041#if defined(AF_INET6)
7042      remote_data_family = AF_INET6;
7043      local_data_family = AF_INET6;
7044#else
7045      fprintf(stderr,
7046	      "This netperf was not compiled on an IPv6 capable host!\n");
7047      fflush(stderr);
7048      exit(-1);
7049#endif
7050      break;
7051    case 'h':
7052      print_omni_usage();
7053      exit(1);
7054    case 'a':
7055      want_defer_accept = 1;
7056      break;
7057    case 'B':
7058      want_use_pktinfo = 1;
7059      break;
7060    case 'b':
7061#ifdef WANT_FIRST_BURST
7062      first_burst_size = atoi(optarg);
7063#else /* WANT_FIRST_BURST */
7064      printf("Initial request burst functionality not compiled-in!\n");
7065#endif /* WANT_FIRST_BURST */
7066      break;
7067    case 'c':
7068      /* this is a connection test */
7069      connection_test = 1;
7070      break;
7071    case 'C':
7072#ifdef TCP_CORK
7073      /* set TCP_CORK */
7074      loc_tcpcork = 1;
7075      rem_tcpcork = 1; /* however, at first, we ony have cork affect loc */
7076#else
7077      printf("WARNING: TCP_CORK not available on this platform!\n");
7078#endif /* TCP_CORK */
7079      break;
7080    case 'd':
7081      /* arbitrarily set the direction variable, but only for an
7082	 actual omni test and then disable implicit setting of
7083	 direction */
7084      if (!was_legacy) {
7085	direction = parse_direction(optarg);
7086	implicit_direction = 0;
7087      }
7088      break;
7089    case 'D':
7090      /* set the TCP nodelay flag */
7091      loc_nodelay = 1;
7092      rem_nodelay = 1;
7093      break;
7094    case 'F':
7095#if defined(MSG_FASTOPEN)
7096      use_fastopen = 1;
7097#else
7098      printf("WARNING: TCP FASTOPEN not available on this platform!\n");
7099#endif
7100      break;
7101    case 'e':
7102      /* set the rEceive timeout */
7103      receive_timeout = atoi(optarg);
7104      break;
7105    case 'g':
7106      /* enable SO_DEBUG, or at least make the attempt, on the data socket */
7107      socket_debug = 1;
7108      break;
7109    case 'G':
7110      /* set the value for a tcp_maxseG call*/
7111      transport_mss_req = atoi(optarg);
7112      break;
7113    case 'H':
7114      break_args_explicit_sep(optarg,',',arg1,arg2);
7115      if (arg1[0]) {
7116	/* check to see if there was a width, which we would want to
7117	   be arg3. for simplicities sake, we will assume the width
7118	   must follow the address and not the address family - ie
7119	   1.2.3.4/24,inet.  This means we can just pass optarg again
7120	   as the source rather than have to shuffle arg values. */
7121	break_args_explicit_sep(optarg,'/',arg1,arg3);
7122	if (arg1[0]) {
7123	  remote_data_address = malloc(strlen(arg1)+1);
7124	  strcpy(remote_data_address,arg1);
7125	  explicit_data_address = 1;
7126	}
7127	if (arg3[0]) {
7128	  remote_mask_len = convert(arg3);
7129	}
7130      }
7131      if (arg2[0]) {
7132	remote_data_family = parse_address_family(arg2);
7133      }
7134      break;
7135    case 'i':
7136      fprintf(stderr,"The support for check_interval has been removed because the contributing editor no longer knew what it was for\n");
7137      fflush(stderr);
7138      break;
7139    case 'I':
7140      use_write = 1;
7141      break;
7142    case 'j':
7143      parallel_connections = atoi(optarg);
7144      break;
7145    case 'k':
7146      netperf_output_mode = KEYVAL;
7147      legacy = 0;
7148      /* obliterate any previous file name */
7149      if (output_selection_spec) {
7150	free(output_selection_spec);
7151	output_selection_spec = NULL;
7152      }
7153      if (argv[optind] && ((unsigned char)argv[optind][0] != '-')) {
7154	/* we assume that what follows is the name of a file with the
7155	   list of desired output values. */
7156	output_selection_spec = strdup(argv[optind]);
7157	optind++;
7158	/* special case - if the file name is "?" then we will emit a
7159	   list of the available outputs */
7160	if (strcmp(output_selection_spec,"?") == 0) {
7161	  dump_netperf_output_choices(stdout,1);
7162	  exit(1);
7163	}
7164      }
7165      break;
7166    case 'K':
7167      /* "Kongestion Kontrol */
7168      break_args(optarg,arg1,arg2);
7169      if (arg1[0])
7170	strncpy(local_cong_control_req,arg1,sizeof(local_cong_control_req));
7171      if (arg2[2])
7172	strncpy(remote_cong_control_req,arg2,sizeof(remote_cong_control_req));
7173      break;
7174    case 'l':
7175      multicast_ttl = atoi(optarg);
7176      break;
7177    case 'L':
7178      break_args_explicit_sep(optarg,',',arg1,arg2);
7179      if (arg1[0]) {
7180	/* check to see if there was a width, which we would want to
7181	   be arg3. for simplicities sake, we will assume the width
7182	   must follow the address and not the address family - ie
7183	   1.2.3.4/24,inet.  This means we can just pass optarg again
7184	   as the source rather than have to shuffle arg values. */
7185	break_args_explicit_sep(optarg,'/',arg1,arg3);
7186	if (arg1[0]) {
7187	  local_data_address = malloc(strlen(arg1)+1);
7188	  strcpy(local_data_address,arg1);
7189	}
7190	if (arg3[0]) {
7191	  local_mask_len = convert(arg3);
7192	}
7193      }
7194      if (arg2[0]) {
7195	local_data_family = parse_address_family(arg2);
7196      }
7197      break;
7198    case 'm':
7199      /* set the send size. if we set the local send size it will add
7200	 XMIT to direction.  if we set the remote send size it will
7201	 add RECV to the direction.  likely as not this will need some
7202	 additional throught */
7203      break_args_explicit(optarg,arg1,arg2);
7204      if (arg1[0]) {
7205	send_size = convert(arg1);
7206	if (implicit_direction)
7207	  direction |= NETPERF_XMIT;
7208      }
7209      if (arg2[0]) {
7210	remote_send_size_req = convert(arg2);
7211	if (implicit_direction)
7212	  direction |= NETPERF_RECV;
7213      }
7214      break;
7215    case 'M':
7216      /* set the recv sizes.  if we set the local recv size it will
7217	 add RECV to direction.  if we set the remote recv size it
7218	 will add XMIT to direction  */
7219      break_args_explicit(optarg,arg1,arg2);
7220      if (arg1[0]) {
7221	remote_recv_size_req = convert(arg1);
7222	if (implicit_direction)
7223	  direction |= NETPERF_XMIT;
7224      }
7225      if (arg2[0]) {
7226	recv_size = convert(arg2);
7227	if (implicit_direction)
7228	  direction |= NETPERF_RECV;
7229      }
7230      break;
7231    case 'n':
7232      /* set the local socket type */
7233      local_connected = 1;
7234      break;
7235    case 'N':
7236      /* set the remote socket type */
7237      remote_connected = 1;
7238      break;
7239    case 'o':
7240      netperf_output_mode = CSV;
7241      legacy = 0;
7242      /* obliterate any previous file name */
7243      if (output_selection_spec) {
7244	free(output_selection_spec);
7245	output_selection_spec = NULL;
7246      }
7247      if (output_selection_spec) {
7248	free(output_selection_spec);
7249	output_selection_spec = NULL;
7250      }
7251      if (argv[optind] && ((unsigned char)argv[optind][0] != '-')) {
7252	/* we assume that what follows is the name of a file with the
7253	   list of desired output values. */
7254	output_selection_spec = strdup(argv[optind]);
7255	optind++;
7256	/* special case - if the file name is "?" then we will emit a
7257	   list of the available outputs */
7258	if (strcmp(output_selection_spec,"?") == 0) {
7259	  dump_netperf_output_choices(stdout,1);
7260	  exit(1);
7261	}
7262      }
7263      break;
7264    case 'O':
7265      netperf_output_mode = HUMAN;
7266      legacy = 0;
7267      /* obliterate any previous file name */
7268      if (output_selection_spec) {
7269	free(output_selection_spec);
7270	output_selection_spec = NULL;
7271      }
7272      if (argv[optind] && ((unsigned char)argv[optind][0] != '-')) {
7273	/* we assume that what follows is the name of a file with the
7274	   list of desired output values */
7275	output_selection_spec = strdup(argv[optind]);
7276	optind++;
7277	if (strcmp(output_selection_spec,"?") == 0) {
7278	  dump_netperf_output_choices(stdout,0);
7279	  exit(1);
7280	}
7281      }
7282      break;
7283    case 'p':
7284      /* set the min and max port numbers for the TCP_CRR and TCP_TRR */
7285      /* tests. */
7286      break_args(optarg,arg1,arg2);
7287      if (arg1[0])
7288	client_port_min = atoi(arg1);
7289      if (arg2[0])
7290	client_port_max = atoi(arg2);
7291      break;
7292    case 'P':
7293      /* set the local and remote data port numbers for the tests to
7294	 allow them to run through those blankety blank end-to-end
7295	 breaking firewalls. raj 2004-06-15 */
7296      break_args(optarg,arg1,arg2);
7297      if (arg1[0])
7298	strncpy(local_data_port,arg1,sizeof(local_data_port));
7299      if (arg2[0])
7300	strncpy(remote_data_port,arg2,sizeof(remote_data_port));
7301      break;
7302    case 'r':
7303      /* set the request/response sizes. setting request/response
7304	 sizes implicitly sets direction to XMIT and RECV */
7305      if (implicit_direction) {
7306	direction |= NETPERF_XMIT;
7307	direction |= NETPERF_RECV;
7308      }
7309      break_args(optarg,arg1,arg2);
7310      if (arg1[0])
7311	req_size = convert(arg1);
7312      if (arg2[0])
7313	rsp_size = convert(arg2);
7314      break;
7315    case 'R':
7316      routing_allowed = atoi(optarg);
7317      have_R_option = 1;
7318      break;
7319    case 's':
7320      /* set local socket sizes */
7321      break_args(optarg,arg1,arg2);
7322      if (arg1[0])
7323	lss_size_req = convert(arg1);
7324      if (arg2[0])
7325	lsr_size_req = convert(arg2);
7326      break;
7327    case 'S':
7328      /* set remote socket sizes */
7329      break_args(optarg,arg1,arg2);
7330      if (arg1[0])
7331	rss_size_req = convert(arg1);
7332      if (arg2[0])
7333	rsr_size_req = convert(arg2);
7334      break;
7335    case 't':
7336      /* set the socket type */
7337      socket_type = parse_socket_type(optarg);
7338      break;
7339    case 'T':
7340      /* set the protocol - aka "Transport" */
7341      protocol = parse_protocol(optarg);
7342      break;
7343    case 'u':
7344      /* use the supplied string as the UUID for this test. at some
7345	 point we may want to sanity check the string we are given but
7346	 for now we won't worry about it */
7347      strncpy(test_uuid,optarg,sizeof(test_uuid));
7348      /* strncpy may leave us with a string without a null at the end */
7349      test_uuid[sizeof(test_uuid) - 1] = 0;
7350      have_uuid = 1;
7351      break;
7352    case 'U':
7353      /* we don't want to give-up on the failure of a connect() call */
7354      dont_give_up = 1;
7355      break;
7356    case 'W':
7357      /* set the "width" of the user space data */
7358      /* buffer. This will be the number of */
7359      /* send_size buffers malloc'd in the */
7360      /* *_STREAM test. It may be enhanced to set */
7361      /* both send and receive "widths" but for now */
7362      /* it is just the sending *_STREAM. */
7363      send_width = convert(optarg);
7364      break;
7365    case 'V' :
7366      /* we want to do copy avoidance and will set */
7367      /* it for everything, everywhere, if we really */
7368      /* can. of course, we don't know anything */
7369      /* about the remote... */
7370      loc_sndavoid = 1;
7371      loc_rcvavoid = 1;
7372      rem_sndavoid = 1;
7373      rem_rcvavoid = 1;
7374      break;
7375    };
7376  }
7377
7378  /* generate the UUID for this test if the user has not supplied it */
7379  if (!have_uuid)
7380    get_uuid_string(test_uuid,sizeof(test_uuid));
7381
7382  protocol_str = protocol_to_str(protocol);
7383  /* ok, if we have gone through all that, and direction is still
7384     zero, let us see if it needs to be set to something else. */
7385  if ((0 == direction) && (!connection_test)) direction = NETPERF_XMIT;
7386  direction_str = direction_to_str(direction);
7387
7388  /* to cover the backside of blithering idiots who run unidirectional
7389     UDP tests on test setups where they might trash their corporate
7390     WAN, we grudgingly provide a safety latch. unless explicitly
7391     enabled, UDP_STREAM/UDP_MAERTS sockets will not allow themselves
7392     to be routed via a gateway. raj 20091026 */
7393
7394  if ((!have_R_option) &&
7395      (protocol == IPPROTO_UDP) &&
7396      (!NETPERF_IS_RR(direction))) {
7397    routing_allowed = 0;
7398  }
7399
7400  /* some other sanity checks we need to make would include stuff when
7401     the user has set -m and -M such that both XMIT and RECV are set
7402     and has not set -r. initially we will not allow that.  at some
7403     point we might allow that if the user has also set -r, but until
7404     then the code will simply ignore the values from -m and -M when
7405     -r is set. */
7406
7407#if defined(WANT_HISTOGRAM)
7408  if (verbosity > 1) keep_histogram = 1;
7409#endif
7410
7411  /* did the user use -d 6 but not set -r? */
7412  if (NETPERF_IS_RR(direction) && !NETPERF_CC(direction)) {
7413    if (req_size == -1)
7414      req_size = 1;
7415    if (rsp_size == -1)
7416      rsp_size = 1;
7417  }
7418
7419  /* ok, time to sanity check the output units */
7420  if ('?' == libfmt) {
7421    /* if this is a RR test then set it to 'x' for transactions */
7422    if (NETPERF_IS_RR(direction)) {
7423      libfmt = 'x';
7424    }
7425    else {
7426      libfmt = 'm';
7427    }
7428  }
7429  else if ('x' == libfmt) {
7430    /* now, a format of 'x' makes no sense for anything other than
7431       an RR test. if someone has been silly enough to try to set
7432       that, we will reset it silently to default - namely 'm' */
7433    if (!NETPERF_IS_RR(direction)) {
7434      libfmt = 'm';
7435    }
7436  }
7437
7438  /* this needs to be strdup :) */
7439  thruput_format_str = strdup(format_units());
7440
7441  /* so, if there is to be no control connection, we want to have some
7442     different settings for a few things */
7443
7444  if (no_control) {
7445    if (strcmp(remote_data_port,"0") == 0) {
7446      /* we need to select either the discard port, echo port or
7447	 chargen port dedepending on the test direction. raj
7448	 20101220 */
7449      if (NETPERF_XMIT_ONLY(direction)) {
7450	strncpy(remote_data_port,"discard",sizeof(remote_data_port));
7451	recv_size = -1;
7452      }
7453      else if (NETPERF_RECV_ONLY(direction)) {
7454	strncpy(remote_data_port,"chargen",sizeof(remote_data_port));
7455	send_size = -1;
7456      }
7457      else if (NETPERF_IS_RR(direction) || NETPERF_CC(direction)) {
7458	strncpy(remote_data_port,"echo",sizeof(remote_data_port));
7459	rsp_size = req_size;
7460      }
7461      else {
7462	printf("No default port known for the %s test, please set one yourself\n",test_name);
7463	exit(-1);
7464      }
7465    }
7466    remote_data_port[sizeof(remote_data_port) - 1] = '\0';
7467
7468    /* I go back and forth on whether these should become -1 or if
7469       they should become 0 for a no_control test. what do you think?
7470       raj 2006-02-08 */
7471
7472    rem_rcvavoid = -1;
7473    rem_sndavoid = -1;
7474    rss_size_req = -1;
7475    rsr_size_req = -1;
7476    rem_nodelay = -1;
7477
7478  }
7479  /* so, did the user request a few things implicitly via output selection? */
7480  if (!legacy)
7481    print_omni_init();
7482
7483  if (desired_output_groups & OMNI_WANT_STATS) {
7484    keep_statistics = 1;
7485    keep_histogram = 1;
7486  }
7487
7488}
7489
7490#endif /* WANT_OMNI */
7491