Home | History | Annotate | Download | only in src
      1 #ifdef HAVE_CONFIG_H
      2 #include <config.h>
      3 #endif
      4 
      5 #ifdef WANT_OMNI
      6 char 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 
    158 static HIST time_hist;
    159 
    160 
    161 
    162 #ifdef WANT_INTERVALS
    163 int interval_count;
    164 unsigned 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
    170 static hrtime_t intvl_one;
    171 static hrtime_t intvl_two;
    172 static hrtime_t intvl_wait_start;
    173 static hrtime_t *intvl_one_ptr = &intvl_one;
    174 static hrtime_t *intvl_two_ptr = &intvl_two;
    175 static hrtime_t *temp_intvl_ptr = &intvl_one;
    176 #elif defined(WIN32)
    177 static LARGE_INTEGER intvl_one;
    178 static LARGE_INTEGER intvl_two;
    179 static LARGE_INTEGER intvl_wait_start;
    180 static LARGE_INTEGER *intvl_one_ptr = &intvl_one;
    181 static LARGE_INTEGER *intvl_two_ptr = &intvl_two;
    182 static LARGE_INTEGER *temp_intvl_ptr = &intvl_one;
    183 #else
    184 static struct timeval intvl_one;
    185 static struct timeval intvl_two;
    186 static struct timeval intvl_wait_start;
    187 static struct timeval *intvl_one_ptr = &intvl_one;
    188 static struct timeval *intvl_two_ptr = &intvl_two;
    189 static 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
    205 sigset_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 
    310 extern void get_uuid_string(char *string, size_t size);
    311 
    312 /* a boatload of globals while I settle things out */
    313 char *output_selection_spec = NULL;
    314 
    315 char test_uuid[38];
    316 
    317 double result_confid_pct = -1.0;
    318 double loc_cpu_confid_pct = -1.0;
    319 double rem_cpu_confid_pct = -1.0;
    320 double interval_pct = -1.0;
    321 
    322 int protocol;
    323 int direction;
    324 int remote_send_size = -1;
    325 int remote_recv_size = -1;
    326 int remote_send_size_req = -1;
    327 int remote_recv_size_req = -1;
    328 int remote_use_sendfile;
    329 
    330 extern int loc_dirty_count;
    331 extern int loc_clean_count;
    332 extern int rem_dirty_count;
    333 extern int rem_clean_count;
    334 int remote_checksum_off;
    335 int connection_test;
    336 int dont_give_up = 0;
    337 int use_fastopen = 0;
    338 int use_write = 0;
    339 int need_to_connect;
    340 int need_connection;
    341 int bytes_to_send;
    342 double bytes_per_send;
    343 int failed_sends;
    344 int bytes_to_recv;
    345 double bytes_per_recv;
    346 int null_message_ok = 0;
    347 
    348 int was_legacy = 0;
    349 int legacy = 0;
    350 int implicit_direction = 0;
    351 int explicit_data_address = 0;
    352 int want_defer_accept = 0;
    353 
    354 uint64_t      trans_completed = 0;
    355 int64_t       units_remaining;
    356 uint64_t      bytes_sent = 0;
    357 uint64_t      bytes_received = 0;
    358 uint64_t      local_send_calls = 0;
    359 uint64_t      local_receive_calls = 0;
    360 uint64_t      remote_bytes_sent;
    361 uint64_t      remote_bytes_received;
    362 uint64_t      remote_send_calls;
    363 uint64_t      remote_receive_calls;
    364 double        bytes_xferd;
    365 double        remote_bytes_xferd;
    366 double        remote_bytes_per_recv;
    367 double        remote_bytes_per_send;
    368 float         elapsed_time;
    369 float         local_cpu_utilization;
    370 float	      local_service_demand;
    371 float         remote_cpu_utilization;
    372 float	      remote_service_demand;
    373 double	      thruput;
    374 double        local_send_thruput;
    375 double        local_recv_thruput;
    376 double        remote_send_thruput;
    377 double        remote_recv_thruput;
    378 
    379 /* kludges for omni output */
    380 double      elapsed_time_double;
    381 double      local_service_demand_double;
    382 double      remote_service_demand_double;
    383 double      transaction_rate = 1.0;
    384 double      rtt_latency = -1.0;
    385 int32_t     transport_mss = -2;
    386 int32_t     local_transport_retrans = -2;
    387 int32_t     remote_transport_retrans = -2;
    388 char        *deprecated_str = "Deprecated";
    389 int         remote_interface_vendor = -2;
    390 int         remote_interface_device = -2;
    391 int         remote_interface_subvendor = -2;
    392 int         remote_interface_subdevice = -2;
    393 int         local_interface_vendor = -2;
    394 int         local_interface_device = -2;
    395 int         local_interface_subvendor = -2;
    396 int         local_interface_subdevice = -2;
    397 int         local_cpu_frequency = 0;
    398 int         remote_cpu_frequency = 0;
    399 
    400 int         local_security_type_id;
    401 int         local_security_enabled_num;
    402 int         remote_security_type_id;
    403 int         remote_security_enabled_num;
    404 
    405 char        local_cong_control[16] = "";
    406 char        remote_cong_control[16] = "";
    407 char        local_cong_control_req[16] = "";
    408 char        remote_cong_control_req[16] = "";
    409 
    410 int         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" */
    417 int         min_latency = -1, max_latency = -1;
    418 /* the percentiles */
    419 int         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 */
    422 double      mean_latency = -1.0, stddev_latency = -1.0;
    423 
    424 /* default to zero to avoid randomizing */
    425 int local_mask_len = 0;
    426 int remote_mask_len = 0;
    427 
    428 int printing_initialized = 0;
    429 
    430 char *sd_str;
    431 char *thruput_format_str;
    432 
    433 char *socket_type_str;
    434 char *protocol_str;
    435 char *direction_str;
    436 
    437 extern int first_burst_size;
    438 
    439 int  parallel_connections = 1;
    440 
    441 static 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 
    447 static int confidence_iteration;
    448 
    449 static  int local_cpu_method;
    450 static  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 */
    454 static int client_port_min = 5000;
    455 static int client_port_max = 65535;
    456 
    457  /* different options for the sockets				*/
    458 
    459 int
    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 
    467 extern int
    468   loc_tcpcork,
    469   rem_tcpcork,
    470   local_connected,
    471   remote_connected;
    472 
    473 enum 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 
    487 enum 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 
    682 unsigned int desired_output_groups = 0;
    683 
    684 typedef 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 
    696 netperf_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 
    704 enum 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 
    710 int want_use_pktinfo = 0;
    711 int use_pktinfo = 0;
    712 int have_pktinfo = 0;
    713 #ifdef IP_PKTINFO
    714 struct in_pktinfo in_pktinfo;
    715 #endif
    716 
    717 char *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 
    727 static unsigned short
    728 get_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 */
    754 static int
    755 is_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 
    781 static void
    782 set_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 */
    815 static void
    816 join_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 
    888 static void
    889 extract_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 
    912 void
    913 pick_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 */
    965 char *
    966 netperf_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 
   1324 void
   1325 print_netperf_output_entry(FILE *where, enum netperf_output_name what)
   1326 {
   1327 }
   1328 
   1329 void print_omni_init_list();
   1330 
   1331 void
   1332 dump_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 
   1346 void
   1347 dump_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 
   1364 void
   1365 dump_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 
   1411 enum netperf_output_name
   1412 match_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 
   1422 enum netperf_output_name
   1423 match_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 
   1468 void
   1469 set_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 
   1508 void
   1509 parse_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 
   1579 void
   1580 parse_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 
   1639 void
   1640 parse_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 
   1705 void
   1706 set_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 
   1755 void
   1756 parse_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 
   1786 static void
   1787 set_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 
   1809 void
   1810 print_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 
   2400 void
   2401 print_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... */
   2442 int
   2443 my_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 
   2490 void
   2491 print_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 
   2609 void
   2610 print_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 
   2645 void
   2646 print_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 
   2775 void
   2776 print_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 
   2810 int
   2811 connect_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 
   2841 static
   2842 int 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 
   2876 int
   2877 send_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)
   2967 static int
   2968 recv_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 
   3082 static
   3083 int 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 
   3136 int
   3137 recv_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 
   3252 int
   3253 close_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 
   3308 int
   3309 disconnect_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
   3392 static void
   3393 dump_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 
   3416 static int
   3417 get_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 
   3457 static void
   3458 get_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 
   3497 static void
   3498 get_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 
   3516 static void
   3517 set_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 
   3527 static void
   3528 set_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 
   3549 static SOCKET
   3550 omni_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 
   3585 static int
   3586 choose_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 
   3610 void
   3611 print_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  */
   3626 static void
   3627 enable_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 
   3645 void
   3646 set_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 
   3701 void
   3702 send_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 
   4940 void
   4941 send_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? */
   4952 const char *
   4953 inet_ntop(int af, const void *src, char *dst, size_t size);
   4954 #endif
   4955 #endif
   4956 
   4957 static void
   4958 set_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 
   4970 /* the name is something of a misnomer since this test could send, or
   4971    receive, or both, but it matches the historical netperf routine
   4972    naming convention for what runs in the netserver context. */
   4973 void
   4974 recv_omni()
   4975 {
   4976 
   4977   struct addrinfo *local_res;
   4978   char local_name[BUFSIZ];
   4979   char port_buffer[PORTBUFSIZE];
   4980 
   4981   struct sockaddr_storage myaddr_in, peeraddr_in;
   4982   int peeraddr_set = 0;
   4983   SOCKET s_listen, data_socket;
   4984   netperf_socklen_t 	addrlen;
   4985 
   4986   struct ring_elt *send_ring;
   4987   struct ring_elt *recv_ring;
   4988 
   4989   int	timed_out = 0;
   4990   int   pad_time = 0;
   4991   int   need_to_connect = 0;
   4992   int   need_to_accept;
   4993   int   connected;
   4994   int   ret;
   4995   uint32_t   temp_recvs;
   4996 
   4997   struct	omni_request_struct	*omni_request;
   4998   struct	omni_response_struct	*omni_response;
   4999   struct	omni_results_struct	*omni_results;
   5000 
   5001   omni_request =
   5002     (struct omni_request_struct *)netperf_request.content.test_specific_data;
   5003   omni_response =
   5004     (struct omni_response_struct *)netperf_response.content.test_specific_data;
   5005   omni_results =
   5006     (struct omni_results_struct *)netperf_response.content.test_specific_data;
   5007 
   5008   if (debug) {
   5009     fprintf(where,"netserver: %s: entered...\n",__FUNCTION__);
   5010     fflush(where);
   5011   }
   5012 
   5013   /* netserver has no good way of knowing where the conversion cutoff
   5014      point is, so we have to fix it after the fact */
   5015   fixup_request_n(OMNI_REQUEST_CONV_CUTOFF);
   5016 
   5017   /* thus fixed-up, we can extract the requested congestion control
   5018      algorithm */
   5019   strncpy(local_cong_control_req,
   5020 	  omni_request->cong_control,
   5021 	  sizeof(local_cong_control_req));
   5022 
   5023   /* based on what we have been told by the remote netperf, we want to
   5024      setup our endpoint for the "data connection" and let the remote
   5025      netperf know the situation. */
   5026 
   5027   if (debug) {
   5028     fprintf(where,"%s: setting the response type...\n",__FUNCTION__);
   5029     fflush(where);
   5030   }
   5031 
   5032   netperf_response.content.response_type = OMNI_RESPONSE;
   5033 
   5034   if (debug) {
   5035     fprintf(where,"%s: the response type is set...\n",__FUNCTION__);
   5036     fflush(where);
   5037   }
   5038 
   5039   /* Grab a socket to listen on, and then listen on it. */
   5040 
   5041   if (debug) {
   5042     fprintf(where,"%s: grabbing a socket...\n",__FUNCTION__);
   5043     fflush(where);
   5044   }
   5045 
   5046   /* create_data_socket expects to find some things in the global
   5047      variables, so set the globals based on the values in the request.
   5048      once the socket has been created, we will set the response values
   5049      based on the updated value of those globals. raj 7/94 */
   5050   lss_size_req    = omni_request->send_buf_size;
   5051   lsr_size_req    = omni_request->recv_buf_size;
   5052   loc_nodelay     = (omni_request->flags) & OMNI_NO_DELAY;
   5053   loc_rcvavoid    = omni_request->so_rcvavoid;
   5054   loc_sndavoid    = omni_request->so_sndavoid;
   5055   routing_allowed = (omni_request->flags) & OMNI_ROUTING_ALLOWED;
   5056   want_keepalive  = (omni_request->flags) & OMNI_WANT_KEEPALIVE;
   5057   local_socket_prio = omni_request->socket_prio;
   5058   local_socket_tos  = omni_request->socket_tos;
   5059   want_defer_accept = omni_request->flags & OMNI_WANT_DEFER_ACCEPT;
   5060 
   5061 #ifdef WANT_INTERVALS
   5062   interval_usecs = omni_request->interval_usecs;
   5063   interval_wate  = interval_usecs / 1000;
   5064   interval_burst = omni_request->interval_burst;
   5065 #else
   5066   interval_usecs = 0;
   5067   interval_wate  = 1;
   5068   interval_burst = 0;
   5069 #endif
   5070 
   5071   connection_test = omni_request->flags & OMNI_CONNECT_TEST;
   5072 #ifdef TCP_FASTOPEN
   5073   use_fastopen = omni_request->flags & OMNI_FASTOPEN;
   5074 #endif
   5075   direction       = omni_request->direction;
   5076   use_pktinfo = (omni_request->flags) & OMNI_USE_PKTINFO;
   5077 
   5078   /* let's be quite certain the fill file string is null terminated */
   5079   omni_request->fill_file[sizeof(omni_request->fill_file) - 1] = '\0';
   5080   strncpy(local_fill_file,
   5081 	  omni_request->fill_file,
   5082 	  sizeof(local_fill_file));
   5083 
   5084   /* kludgy, because I have no way at present to say how many bytes
   5085      needed to be swapped around for the request from which this is
   5086      pulled, and it is probably all wrong for IPv6 :( */
   5087   switch (nf_to_af(omni_request->ipfamily)) {
   5088   case AF_INET6:
   5089     /* yes indeed it is, do nothing, bz */
   5090     break;
   5091   case AF_INET:
   5092   default:
   5093     for (ret=0; ret < 4; ret++) {
   5094       omni_request->netserver_ip[ret] = htonl(omni_request->netserver_ip[ret]);
   5095       omni_request->netperf_ip[ret] = htonl(omni_request->netperf_ip[ret]);
   5096     }
   5097     break;
   5098   }
   5099 
   5100   set_hostname_and_port_2(omni_request->netserver_ip,
   5101 			  local_name,
   5102 			  port_buffer,
   5103 			  nf_to_af(omni_request->ipfamily),
   5104 			  omni_request->data_port);
   5105 
   5106   local_res = complete_addrinfo(local_name,
   5107 				local_name,
   5108 				port_buffer,
   5109 				nf_to_af(omni_request->ipfamily),
   5110 				nst_to_hst(omni_request->socket_type),
   5111 				omni_request->protocol,
   5112 				0);
   5113 
   5114   s_listen = omni_create_data_socket(local_res);
   5115 
   5116   if (s_listen == INVALID_SOCKET) {
   5117     netperf_response.content.serv_errno = errno;
   5118     send_response();
   5119     if (debug) {
   5120       fprintf(where,"could not create data socket\n");
   5121       fflush(where);
   5122     }
   5123     exit(-1);
   5124   }
   5125 
   5126   /* We now alter the message_ptr variables to be at the desired */
   5127   /* alignments with the desired offsets. */
   5128 
   5129   if (debug) {
   5130     fprintf(where,
   5131 	    "recv_omni: requested recv alignment of %d offset %d\n"
   5132 	    "recv_omni: requested send alignment of %d offset %d\n",
   5133 	    omni_request->recv_alignment,
   5134 	    omni_request->recv_offset,
   5135 	    omni_request->send_alignment,
   5136 	    omni_request->send_offset);
   5137     fflush(where);
   5138   }
   5139 
   5140   omni_response->send_size = omni_request->send_size;
   5141   omni_response->send_width = omni_request->send_width;
   5142   omni_response->socket_prio = local_socket_prio;
   5143   omni_response->socket_tos = local_socket_tos;
   5144 
   5145   if (omni_request->direction & NETPERF_XMIT) {
   5146 #ifdef fo
   5147     /* do we need to set multicast ttl? */
   5148     if (is_multicast_addr(remote_res)) {
   5149       /* yes, s_listen - for a UDP test we will be copying it to
   5150 	 data_socket but that hasn't happened yet. raj 20100315 */
   5151       set_multicast_ttl(s_listen);
   5152     }
   5153 #endif
   5154 
   5155     if (omni_request->response_size > 0) {
   5156       /* request/response_test */
   5157       bytes_to_send = omni_request->response_size;
   5158       if (omni_request->send_width == 0) send_width = 1;
   5159       else send_width = omni_request->send_width;
   5160     }
   5161     else {
   5162       if (omni_request->send_size == -1) {
   5163 	bytes_to_send = choose_send_size(lss_size,omni_request->protocol);
   5164       }
   5165       else bytes_to_send = omni_request->send_size;
   5166       /* set the send_width */
   5167       if (omni_request->send_width == 0) {
   5168 	send_width = (lss_size/bytes_to_send) + 1;
   5169 	if (send_width == 1) send_width++;
   5170       }
   5171       else
   5172 	send_width = omni_request->send_width;
   5173     }
   5174     send_ring = allocate_buffer_ring(send_width,
   5175 				     bytes_to_send,
   5176 				     omni_request->send_alignment,
   5177 				     omni_request->send_offset);
   5178 
   5179     omni_response->send_width = send_width;
   5180     omni_response->send_size = bytes_to_send;
   5181   }
   5182 
   5183   omni_response->receive_size = omni_request->receive_size;
   5184   omni_response->recv_width = omni_request->recv_width;
   5185   if (omni_request->direction & NETPERF_RECV) {
   5186 
   5187     /* do we need to join a multicast group? */
   5188     if (is_multicast_addr(local_res)) {
   5189       /* yes, s_listen - for a UDP test we will be copying it to
   5190 	 data_socket but that hasn't happened yet. raj 20100315 */
   5191       join_multicast_addr(s_listen, local_res);
   5192     }
   5193 
   5194     if (omni_request->request_size > 0) {
   5195       /* request/response test */
   5196       bytes_to_recv = omni_request->request_size;
   5197       if (omni_request->recv_width == 0) recv_width = 1;
   5198       else recv_width = omni_request->recv_width;
   5199     }
   5200     else {
   5201       if (omni_request->receive_size == -1) {
   5202 	if (lsr_size > 0) bytes_to_recv = lsr_size;
   5203 	else  bytes_to_recv = 4096;
   5204       }
   5205       else {
   5206 	bytes_to_recv = omni_request->receive_size;
   5207       }
   5208       /* set the recv_width */
   5209       if (omni_request->recv_width == 0) {
   5210 	recv_width = (lsr_size/bytes_to_recv) + 1;
   5211 	if (recv_width == 1) recv_width++;
   5212       }
   5213       else
   5214 	recv_width = omni_request->recv_width;
   5215     }
   5216     recv_ring = allocate_buffer_ring(recv_width,
   5217 				     bytes_to_recv,
   5218 				     omni_request->recv_alignment,
   5219 				     omni_request->recv_offset);
   5220 
   5221     omni_response->receive_size = bytes_to_recv;
   5222     omni_response->recv_width = recv_width;
   5223   }
   5224 
   5225 #ifdef WIN32
   5226   /* The test timer can fire during operations on the listening socket,
   5227      so to make the start_timer below work we have to move
   5228      it to close s_listen while we are blocked on accept. */
   5229   win_kludge_socket2 = s_listen;
   5230 #endif
   5231 
   5232   need_to_accept = (omni_request->protocol != IPPROTO_UDP);
   5233 
   5234   /* we need to hang a listen for everything that needs at least one
   5235      accept. the age-old constant of 5 is probably OK for our purposes
   5236      but does not necessarily represent best practice */
   5237   if (need_to_accept) {
   5238     int backlog = 5;
   5239 #ifdef TCP_FASTOPEN
   5240     /* one of these days I will have to go find-out what the backlog
   5241        is supposed to be here.  until then, I'll just set it to five
   5242        like the listen() call does - it is classic, and was what was
   5243        used in the online example I found */
   5244     if (use_fastopen &&
   5245 	(setsockopt(s_listen,IPPROTO_TCP, TCP_FASTOPEN, &backlog, sizeof(backlog)) ==
   5246 	 SOCKET_ERROR)) {
   5247       netperf_response.content.serv_errno = errno;
   5248       close(s_listen);
   5249       send_response();
   5250       if (debug) {
   5251 	fprintf(where,"netperfserver: %s could not fastopen\n",__FUNCTION__);
   5252 	fflush(where);
   5253       }
   5254       exit(1);
   5255     }
   5256 #endif /* TCP_FASTOPEN */
   5257 #ifdef TCP_DEFER_ACCEPT
   5258     if (want_defer_accept &&
   5259 	(setsockopt(s_listen, IPPROTO_TCP, TCP_DEFER_ACCEPT, &backlog, sizeof(backlog)) == SOCKET_ERROR)) {
   5260       netperf_response.content.serv_errno = errno;
   5261       close(s_listen);
   5262       send_response();
   5263       if (debug) {
   5264 	fprintf(where,
   5265 		"netperfserver: %s could not defer accept\n",__FUNCTION__);
   5266 	fflush(where);
   5267       }
   5268       exit(1);
   5269     }
   5270 #endif /* TCP_DEFER_ACCEPT */
   5271     if (listen(s_listen, backlog) == SOCKET_ERROR) {
   5272       netperf_response.content.serv_errno = errno;
   5273       close(s_listen);
   5274       send_response();
   5275       if (debug) {
   5276 	fprintf(where,"netperfserver: %s could not listen\n",__FUNCTION__);
   5277 	fflush(where);
   5278       }
   5279       exit(1);
   5280     }
   5281   }
   5282 
   5283   /* now get the port number assigned by the system  */
   5284   addrlen = sizeof(myaddr_in);
   5285   if (getsockname(s_listen,
   5286 		  (struct sockaddr *)&myaddr_in,
   5287 		  &addrlen) == SOCKET_ERROR){
   5288     netperf_response.content.serv_errno = errno;
   5289     close(s_listen);
   5290     send_response();
   5291     if (debug) {
   5292       fprintf(where,"could not getsockname\n");
   5293       fflush(where);
   5294     }
   5295     exit(-1);
   5296   }
   5297 
   5298   /* Now myaddr_in contains the port and the internet address this is
   5299      returned to the sender also implicitly telling the sender that
   5300      the socket buffer sizing has been done. likely as not, the IP
   5301      address will be the wildcard - so we only really need to extract
   5302      the port number. since send_response is going to call htonl on
   5303      all the fields, we want to initially put the port number in there
   5304      in host order. */
   5305 
   5306   omni_response->data_port =
   5307     (int) ntohs(((struct sockaddr_in *)&myaddr_in)->sin_port);
   5308   if (debug) {
   5309     fprintf(where,"telling the remote to call me at %d\n",
   5310 	    omni_response->data_port);
   5311     fflush(where);
   5312   }
   5313   netperf_response.content.serv_errno   = 0;
   5314 
   5315   /* But wait, there's more. If the initiator wanted cpu measurements, */
   5316   /* then we must call the calibrate routine, which will return the max */
   5317   /* rate back to the initiator. If the CPU was not to be measured, or */
   5318   /* something went wrong with the calibration, we will return a 0.0 to */
   5319   /* the initiator. */
   5320 
   5321   omni_response->cpu_rate = (float)0.0; 	/* assume no cpu */
   5322   omni_response->flags &= ~OMNI_MEASURE_CPU;
   5323   if (omni_request->flags & OMNI_MEASURE_CPU) {
   5324     omni_response->flags |= OMNI_MEASURE_CPU;
   5325     omni_response->cpu_rate =
   5326       calibrate_local_cpu(omni_request->cpu_rate);
   5327   }
   5328 
   5329   /* before we send the response back to the initiator, pull some of */
   5330   /* the socket parms from the globals */
   5331   omni_response->send_buf_size = lss_size;
   5332   omni_response->recv_buf_size = lsr_size;
   5333   if (loc_nodelay)
   5334     omni_response->flags |= OMNI_NO_DELAY;
   5335   else
   5336     omni_response->flags &= ~OMNI_NO_DELAY;
   5337 
   5338   omni_response->so_rcvavoid = loc_rcvavoid;
   5339   omni_response->so_sndavoid = loc_sndavoid;
   5340   omni_response->interval_usecs = interval_usecs;
   5341   omni_response->interval_burst = interval_burst;
   5342 
   5343   send_response_n(OMNI_RESPONSE_CONV_CUTOFF); /* brittle, but functional */
   5344 
   5345   local_send_calls = 0;
   5346   local_receive_calls = 0;
   5347 
   5348   addrlen = sizeof(peeraddr_in);
   5349   memset(&peeraddr_in,0,sizeof(peeraddr_in));
   5350 
   5351   /* Now it's time to start receiving data on the connection. We will */
   5352   /* first grab the apropriate counters and then start grabbing. */
   5353 
   5354   cpu_start(omni_request->flags & OMNI_MEASURE_CPU);
   5355 
   5356   /* if the test is timed, set a timer of suitable length.  if the
   5357      test is by byte/transaction count, we don't need a timer - or
   5358      rather we rely on the netperf to only ask us to do transaction
   5359      counts over "reliable" protocols.  perhaps at some point we
   5360      should add a check herebouts to verify that... */
   5361 
   5362   if (omni_request->test_length >= 0) {
   5363     times_up = 0;
   5364     units_remaining = 0;
   5365 	test_time=omni_request->test_length;
   5366     /* if we are the sender and only sending, then we don't need/want
   5367        the padding, otherwise, we need the padding */
   5368     if (!(NETPERF_XMIT_ONLY(omni_request->direction)) &&
   5369 	(omni_request->test_length > 0))
   5370       pad_time = PAD_TIME;
   5371     start_timer(omni_request->test_length + pad_time);
   5372   }
   5373   else {
   5374     times_up = 1;
   5375     units_remaining = omni_request->test_length * -1;
   5376   }
   5377 
   5378 #if defined(WANT_INTERVALS)
   5379   INTERVALS_INIT();
   5380 #endif /* WANT_INTERVALS */
   5381 
   5382 
   5383   trans_completed = 0;
   5384   bytes_sent = 0;
   5385   bytes_received = 0;
   5386   connected = 0;
   5387 
   5388   while ((!times_up) || (units_remaining > 0)) {
   5389 
   5390     if (need_to_accept) {
   5391       /* accept a connection from the remote */
   5392 #ifdef WIN32
   5393       /* The test timer will probably fire during this accept,
   5394 	 so to make the start_timer above work we have to move
   5395 	 it to close s_listen while we are blocked on accept. */
   5396       win_kludge_socket = s_listen;
   5397 #endif
   5398       if ((data_socket=accept(s_listen,
   5399 			      (struct sockaddr *)&peeraddr_in,
   5400 			      &addrlen)) == INVALID_SOCKET) {
   5401 	if (errno == EINTR) {
   5402 	  /* the timer popped */
   5403 	  times_up = 1; /* ostensibly the signal hander dealt with this?*/
   5404 	  timed_out = 1;
   5405 	  break;
   5406 	}
   5407 	netperf_response.content.serv_errno = errno;
   5408 	send_response();
   5409 	fprintf(where,"%s: accept: errno = %d\n",__FUNCTION__,errno);
   5410 	fflush(where);
   5411 	close(s_listen);
   5412 
   5413 	exit(-1);
   5414       }
   5415 
   5416       if (debug) {
   5417 	fprintf(where,"%s: accepted data connection.\n",__FUNCTION__);
   5418 	fflush(where);
   5419       }
   5420       need_to_accept = 0;
   5421       connected = 1;
   5422 
   5423 #ifdef KLUDGE_SOCKET_OPTIONS
   5424       /* this is for those systems which *INCORRECTLY* fail to pass
   5425 	 attributes across an accept() call. Including this goes
   5426 	 against my better judgement :( raj 11/95 */
   5427 
   5428       kludge_socket_options(data_socket);
   5429 
   5430 #endif /* KLUDGE_SOCKET_OPTIONS */
   5431 
   5432     }
   5433     else {
   5434       /* I wonder if duping would be better here? we also need to set
   5435 	 peeraddr_in so we can send to netperf if this isn't a
   5436 	 request/response test or if we are going to connect() the
   5437 	 socket, but we only need to do it once. */
   5438       if ((omni_request->protocol == IPPROTO_UDP) &&
   5439 	  (!peeraddr_set)) {
   5440 	peeraddr_set = 1;
   5441 	data_socket = s_listen;
   5442 	set_sockaddr_family_addr_port(&peeraddr_in,
   5443 				      nf_to_af(omni_request->ipfamily),
   5444 				      omni_request->netperf_ip,
   5445 				      omni_request->netperf_port);
   5446       }
   5447     }
   5448 
   5449 #ifdef WIN32
   5450   /* this is used so the timer thread can close the socket out from
   5451      under us, which to date is the easiest/cleanest/least
   5452      Windows-specific way I can find to force the winsock calls to
   5453      return WSAEINTR with the test is over. anything that will run on
   5454      95 and NT and is closer to what netperf expects from Unix signals
   5455      and such would be appreciated raj 1/96 */
   5456   win_kludge_socket = data_socket;
   5457 #endif /* WIN32 */
   5458 
   5459     /* in recv_omni, we check recv first, and _then_ send, otherwise,
   5460        a request/response test will be all messed-up :) and that then
   5461        is why there are two routines to rule them all rather than just
   5462        one :) */
   5463     if ((omni_request->direction & NETPERF_RECV) &&
   5464 	((!times_up) || (units_remaining > 0))) {
   5465       ret = recv_data(data_socket,
   5466 		      recv_ring,
   5467 		      bytes_to_recv,
   5468 		      (connected) ? NULL : (struct sockaddr *)&peeraddr_in,
   5469 		      &addrlen,
   5470 		      /* if XMIT also, then this is RR test so waitall */
   5471 		      (direction & NETPERF_XMIT) ? NETPERF_WAITALL: 0,
   5472 		      &temp_recvs);
   5473       if (ret > 0) {
   5474 	/* if this is a recv-only test controlled by byte count we
   5475 	   decrement the units_remaining by the bytes received */
   5476 	if (!(direction & NETPERF_XMIT) && (units_remaining > 0)) {
   5477 	  units_remaining -= ret;
   5478 	}
   5479 	bytes_received += ret;
   5480 	local_receive_calls += temp_recvs;
   5481       }
   5482       else if (ret == 0) {
   5483 	/* is this the end of a test, just a zero-byte recv, or
   5484 	   something else? that is an exceedingly good question and
   5485 	   one for which I don't presently have a good answer, but
   5486 	   that won't stop me from guessing :) raj 2008-01-09 */
   5487 	if (!((connection_test) || (null_message_ok))) {
   5488 	  /* if it is neither a connection_test nor null_message_ok it
   5489 	     must be the end of the test */
   5490 	  times_up = 1;
   5491 	  break;
   5492 	}
   5493 	local_receive_calls += temp_recvs;
   5494       }
   5495       else if (ret == -1) {
   5496 	/* test timed-out */
   5497 	times_up = 1;
   5498 	timed_out = 1;
   5499 	break;
   5500       }
   5501       else {
   5502 	/* presently at least, -2 and -3 are equally bad on recv */
   5503 	/* we need a response message here for the control connection
   5504 	   before we exit! */
   5505 	netperf_response.content.serv_errno = errno;
   5506 	send_response();
   5507 	exit(-1);
   5508       }
   5509       recv_ring = recv_ring->next;
   5510     }
   5511 
   5512     /* if we should try to send something, then by all means, let us
   5513        try to send something. */
   5514     if ((omni_request->direction & NETPERF_XMIT) &&
   5515 	((!times_up) || (units_remaining > 0))) {
   5516 
   5517       /* there used to be some code here looking sched_yield() until
   5518 	 there was no more queued, unsent data on the socket but
   5519 	 frankly, I've no idea what that was all about so I have
   5520 	 removed it. It may have been part of a kludge to try to avoid
   5521 	 coalescing requests and responses */
   5522 
   5523       if (omni_request->protocol == IPPROTO_UDP && need_to_connect &&
   5524           !connected) {
   5525         if (connect(data_socket,
   5526                     (struct sockaddr*)&peeraddr_in,
   5527                     addrlen) == INVALID_SOCKET) {
   5528 	  netperf_response.content.serv_errno = errno;
   5529 	  send_response();
   5530 	  close(data_socket);
   5531 	  exit(-1);
   5532         }
   5533         connected = 1;
   5534       }
   5535 
   5536       ret = send_data(data_socket,
   5537 		      send_ring,
   5538 		      bytes_to_send,
   5539 		      (connected) ? NULL : (struct sockaddr *)&peeraddr_in,
   5540 		      addrlen,
   5541 		      omni_request->protocol);
   5542 
   5543       /* the order of these if's will seem a triffle strange, but they
   5544 	 are my best guess as to order of probabilty and/or importance
   5545 	 to the overhead raj 2008-01-09*/
   5546       if (ret == bytes_to_send) {
   5547 	/* if this is a send-only test controlled by byte count we
   5548 	   decrement units_remaining by the bytes sent */
   5549 	if (!(direction & NETPERF_RECV) && (units_remaining > 0)) {
   5550 	  units_remaining -= ret;
   5551 	}
   5552 	bytes_sent += ret;
   5553 	send_ring = send_ring->next;
   5554 	local_send_calls++;
   5555       }
   5556       else if (ret == -2) {
   5557 	/* what to do here -2 means a non-fatal error - probably
   5558 	   ENOBUFS and so our send didn't happen.  in the old code for
   5559 	   UDP_STREAM we would just continue in the while loop.  it
   5560 	   isn't clear that is what to do here, so we will simply
   5561 	   increment the failed_sends stat and fall-through. If this
   5562 	   is a UDP_STREAM style of test, the net effect should be the
   5563 	   same. if this is a UDP_RR with a really-big burst count, I
   5564 	   don't think we were checking for ENOBUFS there anyway and
   5565 	   so would have failed.  Here we can just let things
   5566 	   slide. */
   5567 	failed_sends++;
   5568       }
   5569       else if (ret == 0) {
   5570 	/* was this a zero-byte send? if it was, then ostensibly we
   5571 	   would hit the ret == bytes_to_send case which means we'd
   5572 	   never get here as we are using blocking semantics */
   5573       }
   5574       else if (ret == -1) {
   5575 	times_up = 1;
   5576 	timed_out = 1;
   5577 	break;
   5578       }
   5579       else {
   5580 	/* we need a response message back to netperf here before we
   5581 	   exit */
   5582 	/* NEED RESPONSE; */
   5583 	netperf_response.content.serv_errno = errno;
   5584 	send_response();
   5585 	exit(-1);
   5586       }
   5587 
   5588     }
   5589 
   5590     if (connection_test) {
   5591 #ifdef __linux
   5592       /* so, "Linux" with autotuning likes to alter the socket buffer
   5593 	 sizes over the life of the connection, but only does so when
   5594 	 one takes the defaults at time of socket creation.  if we
   5595 	 took those defaults, we should inquire as to what the values
   5596 	 ultimately became. raj 2008-01-15 */
   5597       /* but as annoying as it is to have to make these calls, don't
   5598 	 penalize linux by calling them over and over again. instead
   5599 	 we will simply ass-u-me that it will become the same value
   5600 	 over and over again. raj 20100917 */
   5601       if ((lsr_size_req < 0) && (-1 == lsr_size_end))
   5602 	get_sock_buffer(data_socket, RECV_BUFFER, &lsr_size_end);
   5603       else
   5604 	lsr_size_end = lsr_size;
   5605       if ((lss_size_req < 0) && (-1 == lss_size_end))
   5606 	get_sock_buffer(data_socket, SEND_BUFFER, &lss_size_end);
   5607       else
   5608 	lss_size_end = lss_size;
   5609 #else
   5610       lsr_size_end = lsr_size;
   5611       lss_size_end = lss_size;
   5612 #endif
   5613       ret = close_data_socket(data_socket,NULL,0,omni_request->protocol);
   5614       if (ret == -1) {
   5615 	times_up = 1;
   5616 	timed_out = 1;
   5617 	break;
   5618       }
   5619       else if (ret < 0) {
   5620 	netperf_response.content.serv_errno = errno;
   5621 	send_response();
   5622 	perror("netperf: recv_omni: close_data_socket failed");
   5623 	fflush(where);
   5624 	exit(-1);
   5625       }
   5626       /* we will need a new connection to be established */
   5627       need_to_accept = 1;
   5628       connected = 0;
   5629     }
   5630 
   5631 #if defined(WANT_INTERVALS)
   5632     INTERVALS_WAIT();
   5633 #endif /* WANT_INTERVALS */
   5634 
   5635     /* was this a "transaction" test? don't for get that a TCP_CC
   5636        style test will have no xmit or recv :) so, we check for either
   5637        both XMIT and RECV set, or neither XMIT nor RECV set */
   5638     if (NETPERF_IS_RR(omni_request->direction)) {
   5639       trans_completed++;
   5640       if (units_remaining) {
   5641 	units_remaining--;
   5642       }
   5643     }
   5644   }
   5645 
   5646   /* The current iteration loop now exits due to timeout or unit count
   5647      being  reached */
   5648   stop_timer();
   5649   cpu_stop(omni_request->flags & OMNI_MEASURE_CPU,&elapsed_time);
   5650   close(s_listen);
   5651 
   5652 #if defined(WANT_INTERVALS)
   5653 #ifdef WIN32
   5654   stop_itimer();
   5655 #endif
   5656 #endif /* WANT_INTERVALS */
   5657 
   5658  if (timed_out) {
   5659     /* we ended the test by time, which may have been PAD_TIME seconds
   5660        longer than we wanted to run. so, we want to subtract pad_time
   5661        from the elapsed_time. if we didn't pad the timer pad_time will
   5662        be 0 so we can just subtract it anyway :) */
   5663     if (debug) {
   5664       fprintf(where,"Adjusting elapsed time by %d seconds\n",pad_time);
   5665       fflush(where);
   5666     }
   5667     elapsed_time -= pad_time;
   5668   }
   5669 
   5670   remote_transport_retrans = get_transport_retrans(data_socket,
   5671 						   omni_request->protocol);
   5672 
   5673   if (connected) {
   5674 #ifdef __linux
   5675     /* so, "Linux" with autotuning likes to alter the socket buffer
   5676        sizes over the life of the connection, but only does so when
   5677        one takes the defaults at time of socket creation.  if we took
   5678        those defaults, we should inquire as to what the values
   5679        ultimately became. raj 2008-01-15 */
   5680     if (lsr_size_req < 0)
   5681       get_sock_buffer(data_socket, RECV_BUFFER, &lsr_size_end);
   5682     else
   5683       lsr_size_end = lsr_size;
   5684     if (lss_size_req < 0)
   5685       get_sock_buffer(data_socket, SEND_BUFFER, &lss_size_end);
   5686     else
   5687       lss_size_end = lss_size;
   5688 #else
   5689     lsr_size_end = lsr_size;
   5690     lss_size_end = lss_size;
   5691 #endif
   5692     if (omni_request->flags & OMNI_WANT_REM_CONG) {
   5693       get_transport_cong_control(data_socket,
   5694 				 local_res->ai_protocol,
   5695 				 omni_results->cong_control,
   5696 				 sizeof(omni_results->cong_control));
   5697     }
   5698     else {
   5699       strncpy(omni_results->cong_control,"",sizeof(omni_results->cong_control));
   5700     }
   5701 
   5702 
   5703     close_data_socket(data_socket,NULL,0,omni_request->protocol);
   5704   }
   5705   else {
   5706     close_data_socket(data_socket,(struct sockaddr *)&peeraddr_in,addrlen,omni_request->protocol);
   5707     lsr_size_end = lsr_size;
   5708     lss_size_end = lss_size;
   5709   }
   5710 
   5711   /* send the results to the sender  */
   5712 
   5713   omni_results->send_calls      = (uint32_t) local_send_calls;
   5714   omni_results->bytes_received_lo = bytes_received & 0x00000000FFFFFFFFULL;
   5715   omni_results->bytes_received_hi = (bytes_received & 0xFFFFFFFF00000000ULL) >> 32;
   5716   omni_results->recv_buf_size   = lsr_size_end;
   5717   omni_results->recv_calls      = (uint32_t) local_receive_calls;
   5718   omni_results->bytes_sent_lo   = bytes_sent & 0x00000000FFFFFFFFULL;
   5719   omni_results->bytes_sent_hi   = (bytes_sent & 0xFFFFFFFF00000000ULL) >> 32;
   5720   omni_results->send_buf_size   = lss_size_end;
   5721   omni_results->trans_received	= (uint32_t) trans_completed;
   5722   omni_results->elapsed_time	= elapsed_time;
   5723   omni_results->transport_retrans = remote_transport_retrans;
   5724   omni_results->cpu_method      = cpu_method;
   5725   omni_results->num_cpus        = lib_num_loc_cpus;
   5726   if (omni_request->flags & OMNI_MEASURE_CPU) {
   5727     omni_results->cpu_util            = calc_cpu_util(elapsed_time);
   5728     omni_results->cpu_percent_user    = lib_local_cpu_stats.cpu_user;
   5729     omni_results->cpu_percent_system  = lib_local_cpu_stats.cpu_system;
   5730     omni_results->cpu_percent_iowait  = lib_local_cpu_stats.cpu_iowait;
   5731     omni_results->cpu_percent_irq     = lib_local_cpu_stats.cpu_irq;
   5732     omni_results->cpu_percent_swintr  = lib_local_cpu_stats.cpu_swintr;
   5733     omni_results->peak_cpu_util       = lib_local_cpu_stats.peak_cpu_util;
   5734     omni_results->peak_cpu_id         = lib_local_cpu_stats.peak_cpu_id;
   5735   }
   5736 
   5737 #if defined(WANT_INTERVALS)
   5738 #ifdef WIN32
   5739   stop_itimer();
   5740 #endif
   5741 #endif /* WANT_INTERVALS */
   5742 
   5743   if (debug) {
   5744     fprintf(where,
   5745 	    "%s: test complete, sending results.\n",
   5746 	    __FUNCTION__);
   5747     fflush(where);
   5748   }
   5749 
   5750   send_response_n(OMNI_RESULTS_CONV_CUTOFF);
   5751 
   5752 }
   5753 
   5754 
   5755 #ifdef WANT_MIGRATION
   5757 void
   5758 send_tcp_stream(char remote_host[])
   5759 {
   5760 
   5761   char *tput_title = "\
   5762 Recv   Send    Send                          \n\
   5763 Socket Socket  Message  Elapsed              \n\
   5764 Size   Size    Size     Time     Throughput  \n\
   5765 bytes  bytes   bytes    secs.    %s/sec  \n\n";
   5766 
   5767   char *tput_fmt_0 =
   5768     "%7.2f %s\n";
   5769 
   5770   char *tput_fmt_1 =
   5771     "%6d %6d %6d    %-6.2f   %7.2f   %s\n";
   5772 
   5773   char *cpu_title = "\
   5774 Recv   Send    Send                          Utilization       Service Demand\n\
   5775 Socket Socket  Message  Elapsed              Send     Recv     Send    Recv\n\
   5776 Size   Size    Size     Time     Throughput  local    remote   local   remote\n\
   5777 bytes  bytes   bytes    secs.    %-8.8s/s  %% %c      %% %c      us/KB   us/KB\n\n";
   5778 
   5779   char *cpu_fmt_0 =
   5780     "%6.3f %c %s\n";
   5781 
   5782   char *cpu_fmt_1 =
   5783     "%6d %6d %6d    %-6.2f     %7.2f   %-6.2f   %-6.2f   %-6.3f  %-6.3f %s\n";
   5784 
   5785   char *ksink_fmt = "\n\
   5786 Alignment      Offset         %-8.8s %-8.8s    Sends   %-8.8s Recvs\n\
   5787 Local  Remote  Local  Remote  Xfered   Per                 Per\n\
   5788 Send   Recv    Send   Recv             Send (avg)          Recv (avg)\n\
   5789 %5d   %5d  %5d   %5d %6"PRId64"  %6.2f    %6"PRId64"   %6.2f %6"PRId64"\n";
   5790 
   5791   char *ksink_fmt2 = "\n\
   5792 Maximum\n\
   5793 Segment\n\
   5794 Size (bytes)\n\
   5795 %6d\n";
   5796 
   5797   send_omni_inner(remote_host, legacy, "MIGRATED TCP STREAM TEST");
   5798 
   5799 
   5800   if (legacy) {
   5801 
   5802     /* We are now ready to print all the information, but only if we
   5803        are truly acting as a legacy test. If the user has specified
   5804        zero-level verbosity, we will just print the local service
   5805        demand, or the remote service demand. If the user has requested
   5806        verbosity level 1, he will get the basic "streamperf"
   5807        numbers. If the user has specified a verbosity of greater than
   5808        1, we will display a veritable plethora of background
   5809        information from outside of this block as it it not
   5810        cpu_measurement specific...  */
   5811 
   5812     if (confidence < 0) {
   5813       /* we did not hit confidence, but were we asked to look for it? */
   5814       if (iteration_max > 1) {
   5815 	display_confidence();
   5816       }
   5817     }
   5818 
   5819     if (local_cpu_usage || remote_cpu_usage) {
   5820 
   5821       switch (verbosity) {
   5822       case 0:
   5823 	if (local_cpu_usage) {
   5824 	  fprintf(where,
   5825 		  cpu_fmt_0,
   5826 		  local_service_demand,
   5827 		  local_cpu_method,
   5828 		  ((print_headers) ||
   5829 		   (result_brand == NULL)) ? "" : result_brand);
   5830 	}
   5831 	else {
   5832 	  fprintf(where,
   5833 		  cpu_fmt_0,
   5834 		  remote_service_demand,
   5835 		  remote_cpu_method,
   5836 		  ((print_headers) ||
   5837 		   (result_brand == NULL)) ? "" : result_brand);
   5838 	}
   5839 	break;
   5840       case 1:
   5841       case 2:
   5842 	if (print_headers) {
   5843 	  fprintf(where,
   5844 		  cpu_title,
   5845 		  format_units(),
   5846 		  local_cpu_method,
   5847 		  remote_cpu_method);
   5848 	}
   5849 
   5850 	fprintf(where,
   5851 		cpu_fmt_1,		/* the format string */
   5852 		rsr_size,		/* remote recvbuf size */
   5853 		lss_size,		/* local sendbuf size */
   5854 		send_size,	        /* how large were the sends */
   5855 		elapsed_time,		/* how long was the test */
   5856 		thruput, 		/* what was the xfer rate */
   5857 		local_cpu_utilization,	/* local cpu */
   5858 		remote_cpu_utilization,	/* remote cpu */
   5859 		local_service_demand,	/* local service demand */
   5860 		remote_service_demand,	/* remote service demand */
   5861 		((print_headers) ||
   5862 		 (result_brand == NULL)) ? "" : result_brand);
   5863 	break;
   5864       }
   5865     }
   5866     else {
   5867       /* The tester did not wish to measure service demand. */
   5868 
   5869       switch (verbosity) {
   5870       case 0:
   5871 	fprintf(where,
   5872 		tput_fmt_0,
   5873 		thruput,
   5874 		((print_headers) ||
   5875 		 (result_brand == NULL)) ? "" : result_brand);
   5876 	break;
   5877       case 1:
   5878       case 2:
   5879 	if (print_headers) {
   5880 	  fprintf(where,tput_title,format_units());
   5881 	}
   5882 	fprintf(where,
   5883 		tput_fmt_1,		/* the format string */
   5884 		rsr_size, 		/* remote recvbuf size */
   5885 		lss_size, 		/* local sendbuf size */
   5886 		send_size,	        /* how large were the sends */
   5887 		elapsed_time, 		/* how long did it take */
   5888 		thruput,                /* how fast did it go */
   5889 		((print_headers) ||
   5890 		 (result_brand == NULL)) ? "" : result_brand);
   5891 	break;
   5892       }
   5893     }
   5894 
   5895     /* it would be a good thing to include information about some of the */
   5896     /* other parameters that may have been set for this test, but at the */
   5897     /* moment, I do not wish to figure-out all the  formatting, so I will */
   5898     /* just put this comment here to help remind me that it is something */
   5899     /* that should be done at a later time. */
   5900 
   5901     if (verbosity > 1) {
   5902       /* The user wanted to know it all, so we will give it to him. */
   5903       /* This information will include as much as we can find about */
   5904       /* TCP statistics, the alignments of the sends and receives */
   5905       /* and all that sort of rot... */
   5906 
   5907       /* this stuff needs to be worked-out in the presence of confidence */
   5908       /* intervals and multiple iterations of the test... raj 11/94 */
   5909 
   5910       fprintf(where,
   5911 	      ksink_fmt,
   5912 	      "Bytes",
   5913 	      "Bytes",
   5914 	      "Bytes",
   5915 	      local_send_align,
   5916 	      remote_recv_align,
   5917 	      local_send_offset,
   5918 	      remote_recv_offset,
   5919 	      bytes_sent,
   5920 	      bytes_sent / (double)local_send_calls,
   5921 	      local_send_calls,
   5922 	      bytes_sent / (double)remote_receive_calls,
   5923 	      remote_receive_calls);
   5924       fprintf(where,
   5925 	      ksink_fmt2,
   5926 	      transport_mss);
   5927 #ifdef WANT_HISTOGRAM
   5928       fprintf(where,"\n\nHistogram of time spent in send() call.\n");
   5929       HIST_report(time_hist);
   5930 #endif /* WANT_HISTOGRAM */
   5931       fflush(where);
   5932     }
   5933 
   5934   }
   5935 }
   5936 
   5937 void
   5938 send_tcp_maerts(char remote_host[])
   5939 {
   5940 
   5941   char *tput_title = "\
   5942 Recv   Send    Send                          \n\
   5943 Socket Socket  Message  Elapsed              \n\
   5944 Size   Size    Size     Time     Throughput  \n\
   5945 bytes  bytes   bytes    secs.    %s/sec  \n\n";
   5946 
   5947   char *tput_fmt_0 =
   5948     "%7.2f %s\n";
   5949 
   5950   char *tput_fmt_1 =
   5951     "%6d %6d %6d    %-6.2f   %7.2f   %s\n";
   5952 
   5953   char *cpu_title = "\
   5954 Recv   Send    Send                          Utilization       Service Demand\n\
   5955 Socket Socket  Message  Elapsed              Recv     Send     Recv    Send\n\
   5956 Size   Size    Size     Time     Throughput  local    remote   local   remote\n\
   5957 bytes  bytes   bytes    secs.    %-8.8s/s  %% %c      %% %c      us/KB   us/KB\n\n";
   5958 
   5959   char *cpu_fmt_0 =
   5960     "%6.3f %c %s\n";
   5961 
   5962   char *cpu_fmt_1 =
   5963     "%6d %6d %6d    %-6.2f     %7.2f   %-6.2f   %-6.2f   %-6.3f  %-6.3f %s\n";
   5964 
   5965   char *ksink_fmt = "\n\
   5966 Alignment      Offset         %-8.8s %-8.8s    Recvs   %-8.8s Sends\n\
   5967 Local  Remote  Local  Remote  Xfered   Per                 Per\n\
   5968 Recv   Send    Recv   Send             Recv (avg)          Send (avg)\n\
   5969 %5d   %5d  %5d   %5d %6"PRId64"  %6.2f    %6d   %6.2f %6d\n";
   5970 
   5971   char *ksink_fmt2 = "\n\
   5972 Maximum\n\
   5973 Segment\n\
   5974 Size (bytes)\n\
   5975 %6d\n";
   5976 
   5977   send_omni_inner(remote_host, legacy, "MIGRATED TCP MAERTS TEST");
   5978 
   5979 
   5980   /* We are now ready to print all the information, but only if we are
   5981      truly acting as a leacy test.  If the user has specified
   5982      zero-level verbosity, we will just print the local service
   5983      demand, or the remote service demand. If the user has requested
   5984      verbosity level 1, he will get the basic "streamperf" numbers. If
   5985      the user has specified a verbosity of greater than 1, we will
   5986      display a veritable plethora of background information from
   5987      outside of this block as it it not cpu_measurement
   5988      specific...  */
   5989 
   5990   if (legacy) {
   5991 
   5992     if (confidence < 0) {
   5993       /* we did not hit confidence, but were we asked to look for it? */
   5994       if (iteration_max > 1) {
   5995 	display_confidence();
   5996       }
   5997     }
   5998 
   5999     if (local_cpu_usage || remote_cpu_usage) {
   6000 
   6001       switch (verbosity) {
   6002       case 0:
   6003 	if (local_cpu_usage) {
   6004 	  fprintf(where,
   6005 		  cpu_fmt_0,
   6006 		  local_service_demand,
   6007 		  local_cpu_method,
   6008 		  ((print_headers) ||
   6009 		   (result_brand == NULL)) ? "" : result_brand);
   6010 	}
   6011 	else {
   6012 	  fprintf(where,
   6013 		  cpu_fmt_0,
   6014 		  remote_service_demand,
   6015 		  remote_cpu_method,
   6016 		  ((print_headers) ||
   6017 		   (result_brand == NULL)) ? "" : result_brand);
   6018 	}
   6019 	break;
   6020       case 1:
   6021       case 2:
   6022 	if (print_headers) {
   6023 	  fprintf(where,
   6024 		  cpu_title,
   6025 		  format_units(),
   6026 		  local_cpu_method,
   6027 		  remote_cpu_method);
   6028 	}
   6029 
   6030 	fprintf(where,
   6031 		cpu_fmt_1,		/* the format string */
   6032 		rsr_size,		/* remote recvbuf size */
   6033 		lss_size,		/* local sendbuf size */
   6034 		remote_send_size,	/* how large were the recvs */
   6035 		elapsed_time,		/* how long was the test */
   6036 		thruput, 		/* what was the xfer rate */
   6037 		local_cpu_utilization,	/* local cpu */
   6038 		remote_cpu_utilization,	/* remote cpu */
   6039 		local_service_demand,	/* local service demand */
   6040 		remote_service_demand,	/* remote service demand */
   6041 		((print_headers) ||
   6042 		 (result_brand == NULL)) ? "" : result_brand);
   6043 	break;
   6044       }
   6045     }
   6046     else {
   6047       /* The tester did not wish to measure service demand. */
   6048 
   6049       switch (verbosity) {
   6050       case 0:
   6051 	fprintf(where,
   6052 		tput_fmt_0,
   6053 		thruput,
   6054 		((print_headers) ||
   6055 		 (result_brand == NULL)) ? "" : result_brand);
   6056 	break;
   6057       case 1:
   6058       case 2:
   6059 	if (print_headers) {
   6060 	  fprintf(where,tput_title,format_units());
   6061 	}
   6062 	fprintf(where,
   6063 		tput_fmt_1,		/* the format string */
   6064 		lsr_size, 		/* local recvbuf size */
   6065 		rss_size, 		/* remot sendbuf size */
   6066 		remote_send_size,	/* how large were the recvs */
   6067 		elapsed_time, 		/* how long did it take */
   6068 		thruput,                /* how fast did it go */
   6069 		((print_headers) ||
   6070 		 (result_brand == NULL)) ? "" : result_brand);
   6071 	break;
   6072       }
   6073     }
   6074 
   6075     /* it would be a good thing to include information about some of the */
   6076     /* other parameters that may have been set for this test, but at the */
   6077     /* moment, I do not wish to figure-out all the  formatting, so I will */
   6078     /* just put this comment here to help remind me that it is something */
   6079     /* that should be done at a later time. */
   6080 
   6081     if (verbosity > 1) {
   6082       /* The user wanted to know it all, so we will give it to him. */
   6083       /* This information will include as much as we can find about */
   6084       /* TCP statistics, the alignments of the sends and receives */
   6085       /* and all that sort of rot... */
   6086 
   6087       /* this stuff needs to be worked-out in the presence of confidence */
   6088       /* intervals and multiple iterations of the test... raj 11/94 */
   6089 
   6090       fprintf(where,
   6091 	      ksink_fmt,
   6092 	      "Bytes",
   6093 	      "Bytes",
   6094 	      "Bytes",
   6095 	      local_recv_align,
   6096 	      remote_recv_align,
   6097 	      local_recv_offset,
   6098 	      remote_recv_offset,
   6099 	      bytes_received,
   6100 	      bytes_received / (double)local_receive_calls,
   6101 	      local_receive_calls,
   6102 	      remote_bytes_sent / (double)remote_send_calls,
   6103 	      remote_send_calls);
   6104       fprintf(where,
   6105 	      ksink_fmt2,
   6106 	      transport_mss);
   6107 
   6108 #ifdef WANT_HISTOGRAM
   6109       fprintf(where,"\n\nHistogram of time spent in recv() call.\n");
   6110       HIST_report(time_hist);
   6111 #endif /* WANT_HISTOGRAM */
   6112       fflush(where);
   6113     }
   6114   }
   6115 }
   6116 
   6117 
   6118 void
   6120 send_tcp_rr(char remote_host[]) {
   6121 
   6122   char *tput_title = "\
   6123 Local /Remote\n\
   6124 Socket Size   Request  Resp.   Elapsed  Trans.\n\
   6125 Send   Recv   Size     Size    Time     Rate         \n\
   6126 bytes  Bytes  bytes    bytes   secs.    per sec   \n\n";
   6127 
   6128   char *tput_title_band = "\
   6129 Local /Remote\n\
   6130 Socket Size   Request  Resp.   Elapsed  \n\
   6131 Send   Recv   Size     Size    Time     Throughput \n\
   6132 bytes  Bytes  bytes    bytes   secs.    %s/sec   \n\n";
   6133 
   6134   char *tput_fmt_0 =
   6135     "%7.2f %s\n";
   6136 
   6137   char *tput_fmt_1_line_1 = "\
   6138 %-6d %-6d %-6d   %-6d  %-6.2f   %7.2f   %s\n";
   6139   char *tput_fmt_1_line_2 = "\
   6140 %-6d %-6d\n";
   6141 
   6142   char *cpu_title = "\
   6143 Local /Remote\n\
   6144 Socket Size   Request Resp.  Elapsed Trans.   CPU    CPU    S.dem   S.dem\n\
   6145 Send   Recv   Size    Size   Time    Rate     local  remote local   remote\n\
   6146 bytes  bytes  bytes   bytes  secs.   per sec  %% %c    %% %c    us/Tr   us/Tr\n\n";
   6147 
   6148   char *cpu_title_tput = "\
   6149 Local /Remote\n\
   6150 Socket Size   Request Resp.  Elapsed Tput     CPU    CPU    S.dem   S.dem\n\
   6151 Send   Recv   Size    Size   Time    %-8.8s local  remote local   remote\n\
   6152 bytes  bytes  bytes   bytes  secs.   per sec  %% %c    %% %c    us/KB   us/KB\n\n";
   6153 
   6154   char *cpu_title_latency = "\
   6155 Local /Remote\n\
   6156 Socket Size   Request Resp.  Elapsed Latency  CPU    CPU    S.dem   S.dem\n\
   6157 Send   Recv   Size    Size   Time    usecs    local  remote local   remote\n\
   6158 bytes  bytes  bytes   bytes  secs.   per tran %% %c    %% %c    us/Tr   us/Tr\n\n";
   6159 
   6160   char *cpu_fmt_0 =
   6161     "%6.3f %c %s\n";
   6162 
   6163   char *cpu_fmt_1_line_1 = "\
   6164 %-6d %-6d %-6d  %-6d %-6.2f  %-6.2f  %-6.2f %-6.2f %-6.3f  %-6.3f %s\n";
   6165 
   6166   char *cpu_fmt_1_line_2 = "\
   6167 %-6d %-6d\n";
   6168 
   6169   char *ksink_fmt = "\
   6170 Alignment      Offset         RoundTrip  Trans    Throughput\n\
   6171 Local  Remote  Local  Remote  Latency    Rate     %-8.8s/s\n\
   6172 Send   Recv    Send   Recv    usec/Tran  per sec  Outbound   Inbound\n\
   6173 %5d  %5d   %5d  %5d   %-6.3f   %-6.3f %-6.3f    %-6.3f\n";
   6174 
   6175   send_omni_inner(remote_host, legacy, "MIGRATED TCP REQUEST/RESPONSE TEST");
   6176 
   6177   if (legacy) {
   6178     /* We are now ready to print all the information. If the user has
   6179        specified zero-level verbosity, we will just print the local
   6180        service demand, or the remote service demand. If the user has
   6181        requested verbosity level 1, he will get the basic "streamperf"
   6182        numbers. If the user has specified a verbosity of greater than 1,
   6183        we will display a veritable plethora of background information
   6184        from outside of this block as it it not cpu_measurement
   6185        specific...  */
   6186 
   6187     if (confidence < 0) {
   6188       /* we did not hit confidence, but were we asked to look for it? */
   6189       if (iteration_max > 1) {
   6190 	display_confidence();
   6191       }
   6192     }
   6193 
   6194     if (local_cpu_usage || remote_cpu_usage) {
   6195 
   6196       switch (verbosity) {
   6197       case 0:
   6198 	if (local_cpu_usage) {
   6199 	  fprintf(where,
   6200 		  cpu_fmt_0,
   6201 		  local_service_demand,
   6202 		  local_cpu_method,
   6203 		  ((print_headers) ||
   6204 		   (result_brand == NULL)) ? "" : result_brand);
   6205 	}
   6206 	else {
   6207 	  fprintf(where,
   6208 		  cpu_fmt_0,
   6209 		  remote_service_demand,
   6210 		  remote_cpu_method,
   6211 		  ((print_headers) ||
   6212 		   (result_brand == NULL)) ? "" : result_brand);
   6213 	}
   6214 	break;
   6215       case 1:
   6216       case 2:
   6217 	if (print_headers) {
   6218 	  if ('x' == libfmt) {
   6219 	    fprintf(where,
   6220 		    cpu_title,
   6221 		    local_cpu_method,
   6222 		    remote_cpu_method);
   6223 	  }
   6224 	  else {
   6225 	    fprintf(where,
   6226 		    cpu_title_tput,
   6227 		    format_units(),
   6228 		    local_cpu_method,
   6229 		    remote_cpu_method);
   6230 	  }
   6231 	}
   6232 
   6233 	fprintf(where,
   6234 		cpu_fmt_1_line_1,		/* the format string */
   6235 		lss_size,		/* local sendbuf size */
   6236 		lsr_size,
   6237 		req_size,		/* how large were the requests */
   6238 		rsp_size,		/* guess */
   6239 		elapsed_time,		/* how long was the test */
   6240 		thruput,
   6241 		local_cpu_utilization,	/* local cpu */
   6242 		remote_cpu_utilization,	/* remote cpu */
   6243 		local_service_demand,	/* local service demand */
   6244 		remote_service_demand,	/* remote service demand */
   6245 		((print_headers) ||
   6246 		 (result_brand == NULL)) ? "" : result_brand);
   6247 	fprintf(where,
   6248 		cpu_fmt_1_line_2,
   6249 		rss_size,
   6250 		rsr_size);
   6251 	break;
   6252       }
   6253     }
   6254     else {
   6255       /* The tester did not wish to measure service demand. */
   6256 
   6257       switch (verbosity) {
   6258       case 0:
   6259 	fprintf(where,
   6260 		tput_fmt_0,
   6261 		thruput,
   6262 		((print_headers) ||
   6263 		 (result_brand == NULL)) ? "" : result_brand);
   6264 	break;
   6265       case 1:
   6266       case 2:
   6267 	if (print_headers) {
   6268 	  fprintf(where,
   6269 		  ('x' == libfmt) ? tput_title : tput_title_band,
   6270 		  format_units());
   6271 	}
   6272 
   6273 	fprintf(where,
   6274 		tput_fmt_1_line_1,	/* the format string */
   6275 		lss_size,
   6276 		lsr_size,
   6277 		req_size,		/* how large were the requests */
   6278 		rsp_size,		/* how large were the responses */
   6279 		elapsed_time, 		/* how long did it take */
   6280 		/* are we trans or do we need to convert to bytes then
   6281 		   bits? at this point, thruput is in our "confident"
   6282 		   transactions per second. we can convert to a
   6283 		   bidirectional bitrate by multiplying that by the sum
   6284 		   of the req_size and rsp_size.  we pass that to
   6285 		   calc_thruput_interval_omni with an elapsed time of
   6286 		   1.0 s to get it converted to [kmg]bits/s or
   6287 		   [KMG]Bytes/s */
   6288 		thruput,
   6289 		((print_headers) ||
   6290 		 (result_brand == NULL)) ? "" : result_brand);
   6291 	fprintf(where,
   6292 		tput_fmt_1_line_2,
   6293 		rss_size, 		/* remote recvbuf size */
   6294 		rsr_size);
   6295 
   6296 	break;
   6297       }
   6298     }
   6299 
   6300     /* it would be a good thing to include information about some of the */
   6301     /* other parameters that may have been set for this test, but at the */
   6302     /* moment, I do not wish to figure-out all the  formatting, so I will */
   6303     /* just put this comment here to help remind me that it is something */
   6304     /* that should be done at a later time. */
   6305 
   6306     /* how to handle the verbose information in the presence of */
   6307     /* confidence intervals is yet to be determined... raj 11/94 */
   6308     if (verbosity > 1) {
   6309       /* The user wanted to know it all, so we will give it to him. */
   6310       /* This information will include as much as we can find about */
   6311       /* TCP statistics, the alignments of the sends and receives */
   6312       /* and all that sort of rot... */
   6313 
   6314       /* normally, you might think that if we were messing about with
   6315 	 the value of libfmt we would need to put it back again, but
   6316 	 since this is basically the last thing we are going to do with
   6317 	 it, it does not matter.  so there :) raj 2007-06-08 */
   6318       /* if the user was asking for transactions, then we report
   6319 	 megabits per second for the unidirectional throughput,
   6320 	 otherwise we use the desired units. */
   6321       if ('x' == libfmt) {
   6322 	libfmt = 'm';
   6323       }
   6324 
   6325       fprintf(where,
   6326 	      ksink_fmt,
   6327 	      format_units(),
   6328 	      local_send_align,
   6329 	      remote_recv_offset,
   6330 	      local_send_offset,
   6331 	      remote_recv_offset,
   6332 	      /* if the user has enable burst mode, we have to remember
   6333 		 to account for that in the number of transactions
   6334 		 outstanding at any one time. otherwise we will
   6335 		 underreport the latency of individual
   6336 		 transactions. learned from saf by raj 2007-06-08  */
   6337 	      (((double)1.0/transaction_rate)*(double)1000000.0) *
   6338 	      (double) (1 + ((first_burst_size > 0) ? first_burst_size : 0)),
   6339 	      transaction_rate,
   6340 	      calc_thruput_interval_omni(transaction_rate * (double)req_size,
   6341 					 1.0),
   6342 	      calc_thruput_interval_omni(transaction_rate * (double)rsp_size,
   6343 					 1.0));
   6344 
   6345 #ifdef WANT_HISTOGRAM
   6346       fprintf(where,"\nHistogram of request/response times\n");
   6347       HIST_report(time_hist);
   6348 #endif /* WANT_HISTOGRAM */
   6349       fflush(where);
   6350     }
   6351   }
   6352 }
   6353 
   6354 
   6355 void
   6356 send_tcp_conn_rr(char remote_host[])
   6357 {
   6358 
   6359   char *tput_title = "\
   6360 Local /Remote\n\
   6361 Socket Size   Request  Resp.   Elapsed  Trans.\n\
   6362 Send   Recv   Size     Size    Time     Rate         \n\
   6363 bytes  Bytes  bytes    bytes   secs.    per sec   \n\n";
   6364 
   6365   char *tput_fmt_0 =
   6366     "%7.2f\n";
   6367 
   6368   char *tput_fmt_1_line_1 = "\
   6369 %-6d %-6d %-6d   %-6d  %-6.2f   %7.2f   \n";
   6370   char *tput_fmt_1_line_2 = "\
   6371 %-6d %-6d\n";
   6372 
   6373   char *cpu_title = "\
   6374 Local /Remote\n\
   6375 Socket Size   Request Resp.  Elapsed Trans.   CPU    CPU    S.dem   S.dem\n\
   6376 Send   Recv   Size    Size   Time    Rate     local  remote local   remote\n\
   6377 bytes  bytes  bytes   bytes  secs.   per sec  %%      %%      us/Tr   us/Tr\n\n";
   6378 
   6379   char *cpu_fmt_0 =
   6380     "%6.3f\n";
   6381 
   6382   char *cpu_fmt_1_line_1 = "\
   6383 %-6d %-6d %-6d  %-6d %-6.2f  %-6.2f   %-6.2f %-6.2f %-6.3f  %-6.3f\n";
   6384 
   6385   char *cpu_fmt_1_line_2 = "\
   6386 %-6d %-6d\n";
   6387 
   6388   char *ksink_fmt = "\n\
   6389 Alignment      Offset\n\
   6390 Local  Remote  Local  Remote\n\
   6391 Send   Recv    Send   Recv\n\
   6392 %5d  %5d   %5d  %5d\n";
   6393 
   6394   send_omni_inner(remote_host,
   6395 		  legacy,
   6396 		  "MIGRATED TCP Connect/Request/Response TEST");
   6397 
   6398   /* We are now ready to print all the information. If the user */
   6399   /* has specified zero-level verbosity, we will just print the */
   6400   /* local service demand, or the remote service demand. If the */
   6401   /* user has requested verbosity level 1, he will get the basic */
   6402   /* "streamperf" numbers. If the user has specified a verbosity */
   6403   /* of greater than 1, we will display a veritable plethora of */
   6404   /* background information from outside of this block as it it */
   6405   /* not cpu_measurement specific...  */
   6406 
   6407   if (legacy) {
   6408     if (confidence < 0) {
   6409       /* we did not hit confidence, but were we asked to look for it? */
   6410       if (iteration_max > 1) {
   6411 	display_confidence();
   6412       }
   6413     }
   6414 
   6415     if (local_cpu_usage || remote_cpu_usage) {
   6416 
   6417       switch (verbosity) {
   6418       case 0:
   6419 	if (local_cpu_usage) {
   6420 	  fprintf(where,
   6421 		  cpu_fmt_0,
   6422 		  local_service_demand,
   6423 		  local_cpu_method);
   6424 	}
   6425 	else {
   6426 	  fprintf(where,
   6427 		  cpu_fmt_0,
   6428 		  remote_service_demand,
   6429 		  remote_cpu_method);
   6430 	}
   6431 	break;
   6432       case 1:
   6433       case 2:
   6434 	if (print_headers) {
   6435 	  fprintf(where,
   6436 		  cpu_title,
   6437 		  local_cpu_method,
   6438 		  remote_cpu_method);
   6439 	}
   6440 
   6441 	fprintf(where,
   6442 		cpu_fmt_1_line_1,	/* the format string */
   6443 		lss_size,		/* local sendbuf size */
   6444 		lsr_size,
   6445 		req_size,		/* how large were the requests */
   6446 		rsp_size,		/* guess */
   6447 		elapsed_time,		/* how long was the test */
   6448 		thruput,
   6449 		local_cpu_utilization,	/* local cpu */
   6450 		remote_cpu_utilization,	/* remote cpu */
   6451 		local_service_demand,	/* local service demand */
   6452 		remote_service_demand);	/* remote service demand */
   6453 	fprintf(where,
   6454 		cpu_fmt_1_line_2,
   6455 		rss_size,
   6456 		rsr_size);
   6457 	break;
   6458       }
   6459     }
   6460     else {
   6461       /* The tester did not wish to measure service demand. */
   6462 
   6463       switch (verbosity) {
   6464       case 0:
   6465 	fprintf(where,
   6466 		tput_fmt_0,
   6467 		thruput);
   6468 	break;
   6469       case 1:
   6470       case 2:
   6471 	if (print_headers) {
   6472 	  fprintf(where,tput_title,format_units());
   6473 	}
   6474 
   6475 	fprintf(where,
   6476 		tput_fmt_1_line_1,	/* the format string */
   6477 		lss_size,
   6478 		lsr_size,
   6479 		req_size,		/* how large were the requests */
   6480 		rsp_size,		/* how large were the responses */
   6481 		elapsed_time, 		/* how long did it take */
   6482 		thruput);
   6483 	fprintf(where,
   6484 		tput_fmt_1_line_2,
   6485 		rss_size, 		/* remote recvbuf size */
   6486 		rsr_size);
   6487 
   6488 	break;
   6489       }
   6490     }
   6491 
   6492     /* it would be a good thing to include information about some of the */
   6493     /* other parameters that may have been set for this test, but at the */
   6494     /* moment, I do not wish to figure-out all the  formatting, so I will */
   6495     /* just put this comment here to help remind me that it is something */
   6496     /* that should be done at a later time. */
   6497 
   6498     /* how to handle the verbose information in the presence of */
   6499     /* confidence intervals is yet to be determined... raj 11/94 */
   6500     if (verbosity > 1) {
   6501       /* The user wanted to know it all, so we will give it to him. */
   6502       /* This information will include as much as we can find about */
   6503       /* TCP statistics, the alignments of the sends and receives */
   6504       /* and all that sort of rot... */
   6505 
   6506       fprintf(where,
   6507 	      ksink_fmt,
   6508 	      local_send_align,
   6509 	      remote_recv_align,
   6510 	      local_send_offset,
   6511 	      remote_recv_offset);
   6512 
   6513 #ifdef WANT_HISTOGRAM
   6514       fprintf(where,"\nHistogram of request/response times\n");
   6515       HIST_report(time_hist);
   6516 #endif /* WANT_HISTOGRAM */
   6517       fflush(where);
   6518     }
   6519   }
   6520 }
   6521 
   6522 void
   6523 send_udp_stream(char remote_host[])
   6524 {
   6525   /**********************************************************************/
   6526   /*									*/
   6527   /*               	UDP Unidirectional Send Test                    */
   6528   /*									*/
   6529   /**********************************************************************/
   6530 
   6531   char *tput_title = "\
   6532 Socket  Message  Elapsed      Messages                \n\
   6533 Size    Size     Time         Okay Errors   Throughput\n\
   6534 bytes   bytes    secs            #      #   %s/sec\n\n";
   6535 
   6536   char *tput_fmt_0 =
   6537     "%7.2f\n";
   6538 
   6539   char *tput_fmt_1 = "\
   6540 %6d  %6d   %-7.2f   %7"PRIu64" %6d    %7.2f\n\
   6541 %6d           %-7.2f   %7"PRIu64"           %7.2f\n\n";
   6542 
   6543 
   6544   char *cpu_title = "\
   6545 Socket  Message  Elapsed      Messages                   CPU      Service\n\
   6546 Size    Size     Time         Okay Errors   Throughput   Util     Demand\n\
   6547 bytes   bytes    secs            #      #   %s/sec %% %c%c     us/KB\n\n";
   6548 
   6549   char *cpu_fmt_0 =
   6550     "%6.2f %c\n";
   6551 
   6552   char *cpu_fmt_1 = "\
   6553 %6d  %6d   %-7.2f   %7"PRIu64" %6d    %7.1f     %-6.2f   %-6.3f\n\
   6554 %6d           %-7.2f   %7"PRIu64"           %7.1f     %-6.2f   %-6.3f\n\n";
   6555 
   6556 
   6557   send_omni_inner(remote_host, legacy, "MIGRATED UDP STREAM TEST");
   6558 
   6559   if (legacy) {
   6560     /* We are now ready to print all the information. If the user has
   6561        specified zero-level verbosity, we will just print the local
   6562        service demand, or the remote service demand. If the user has
   6563        requested verbosity level 1, he will get the basic "streamperf"
   6564        numbers. If the user has specified a verbosity of greater than
   6565        1, we will display a veritable plethora of background
   6566        information from outside of this block as it it not
   6567        cpu_measurement specific...  */
   6568 
   6569 
   6570     if (confidence < 0) {
   6571       /* we did not hit confidence, but were we asked to look for it? */
   6572       if (iteration_max > 1) {
   6573 	display_confidence();
   6574       }
   6575     }
   6576 
   6577     if (local_cpu_usage || remote_cpu_usage) {
   6578 
   6579       switch (verbosity) {
   6580       case 0:
   6581 	if (local_cpu_usage) {
   6582 	  fprintf(where,
   6583 		  cpu_fmt_0,
   6584 		  local_service_demand,
   6585 		  local_cpu_method);
   6586 	}
   6587 	else {
   6588 	  fprintf(where,
   6589 		  cpu_fmt_0,
   6590 		  remote_service_demand,
   6591 		  local_cpu_method);
   6592 	}
   6593 	break;
   6594       case 1:
   6595       case 2:
   6596 	if (print_headers) {
   6597 	  fprintf(where,
   6598 		  cpu_title,
   6599 		  format_units(),
   6600 		  local_cpu_method,
   6601 		  remote_cpu_method);
   6602 	}
   6603 
   6604 	fprintf(where,
   6605 		cpu_fmt_1,		/* the format string */
   6606 		lss_size,		/* local sendbuf size */
   6607 		send_size,		/* how large were the sends */
   6608 		elapsed_time,		/* how long was the test */
   6609 		local_send_calls,
   6610 		failed_sends,
   6611 		local_send_thruput, 	/* what was the xfer rate */
   6612 		local_cpu_utilization,	/* local cpu */
   6613 		local_service_demand,	/* local service demand */
   6614 		rsr_size,
   6615 		elapsed_time,
   6616 		remote_receive_calls,
   6617 		remote_recv_thruput,
   6618 		remote_cpu_utilization,	/* remote cpu */
   6619 		remote_service_demand);	/* remote service demand */
   6620 	break;
   6621       }
   6622     }
   6623     else {
   6624       /* The tester did not wish to measure service demand. */
   6625       switch (verbosity) {
   6626       case 0:
   6627 	fprintf(where,
   6628 		tput_fmt_0,
   6629 		local_send_thruput);
   6630 	break;
   6631       case 1:
   6632       case 2:
   6633 	if (print_headers) {
   6634 	  fprintf(where,tput_title,format_units());
   6635 	}
   6636 	fprintf(where,
   6637 		tput_fmt_1,		/* the format string */
   6638 		lss_size, 		/* local sendbuf size */
   6639 		send_size,		/* how large were the sends */
   6640 		elapsed_time, 		/* how long did it take */
   6641 		local_send_calls,
   6642 		failed_sends,
   6643 		local_send_thruput,
   6644 		rsr_size, 		/* remote recvbuf size */
   6645 		elapsed_time,
   6646 		remote_receive_calls,
   6647 		remote_recv_thruput);
   6648 	break;
   6649       }
   6650     }
   6651 
   6652 #ifdef WANT_HISTOGRAM
   6653     if (verbosity > 1) {
   6654       fprintf(where,"\nHistogram of time spent in send() call\n");
   6655       HIST_report(time_hist);
   6656     }
   6657 #endif /* WANT_HISTOGRAM */
   6658     fflush(where);
   6659   }
   6660 }
   6661 
   6662 void
   6663 send_udp_rr(char remote_host[])
   6664 {
   6665 
   6666   char *tput_title = "\
   6667 Local /Remote\n\
   6668 Socket Size   Request  Resp.   Elapsed  Trans.\n\
   6669 Send   Recv   Size     Size    Time     Rate         \n\
   6670 bytes  Bytes  bytes    bytes   secs.    per sec   \n\n";
   6671 
   6672   char *tput_title_band = "\
   6673 Local /Remote\n\
   6674 Socket Size   Request  Resp.   Elapsed  \n\
   6675 Send   Recv   Size     Size    Time     Throughput \n\
   6676 bytes  Bytes  bytes    bytes   secs.    %s/sec   \n\n";
   6677 
   6678   char *tput_fmt_0 =
   6679     "%7.2f %s\n";
   6680 
   6681   char *tput_fmt_1_line_1 = "\
   6682 %-6d %-6d %-6d   %-6d  %-6.2f   %7.2f   %s\n";
   6683 
   6684   char *tput_fmt_1_line_2 = "\
   6685 %-6d %-6d\n";
   6686 
   6687   char *cpu_title = "\
   6688 Local /Remote\n\
   6689 Socket Size   Request Resp.  Elapsed Trans.   CPU    CPU    S.dem   S.dem\n\
   6690 Send   Recv   Size    Size   Time    Rate     local  remote local   remote\n\
   6691 bytes  bytes  bytes   bytes  secs.   per sec  %% %c    %% %c    us/Tr   us/Tr\n\n";
   6692 
   6693   char *cpu_title_tput = "\
   6694 Local /Remote\n\
   6695 Socket Size   Request Resp.  Elapsed Tput     CPU    CPU    S.dem   S.dem\n\
   6696 Send   Recv   Size    Size   Time    %-8.8s local  remote local   remote\n\
   6697 bytes  bytes  bytes   bytes  secs.   per sec  %% %c    %% %c    us/KB   us/KB\n\n";
   6698 
   6699   char *cpu_fmt_0 =
   6700     "%6.3f %c %s\n";
   6701 
   6702   char *cpu_fmt_1_line_1 = "\
   6703 %-6d %-6d %-6d  %-6d %-6.2f  %-6.2f   %-6.2f %-6.2f %-6.3f  %-6.3f %s\n";
   6704 
   6705   char *cpu_fmt_1_line_2 = "\
   6706 %-6d %-6d\n";
   6707 
   6708   send_omni_inner(remote_host, legacy, "MIGRATED UDP REQUEST/RESPONSE TEST");
   6709 
   6710   if (legacy) {
   6711     /* We are now ready to print all the information. If the user has
   6712        specified zero-level verbosity, we will just print the local
   6713        service demand, or the remote service demand. If the user has
   6714        requested verbosity level 1, he will get the basic "streamperf"
   6715        numbers. If the user has specified a verbosity of greater than
   6716        1, we will display a veritable plethora of background
   6717        information from outside of this block as it it not
   6718        cpu_measurement specific...  */
   6719 
   6720     if (confidence < 0) {
   6721       /* we did not hit confidence, but were we asked to look for it? */
   6722       if (iteration_max > 1) {
   6723 	display_confidence();
   6724       }
   6725     }
   6726 
   6727     if (local_cpu_usage || remote_cpu_usage) {
   6728 
   6729       switch (verbosity) {
   6730       case 0:
   6731 	if (local_cpu_usage) {
   6732 	  fprintf(where,
   6733 		  cpu_fmt_0,
   6734 		  local_service_demand,
   6735 		  local_cpu_method,
   6736 		  ((print_headers) ||
   6737 		   (result_brand == NULL)) ? "" : result_brand);
   6738 
   6739 	}
   6740 	else {
   6741 	  fprintf(where,
   6742 		  cpu_fmt_0,
   6743 		  remote_service_demand,
   6744 		  remote_cpu_method,
   6745 		  ((print_headers) ||
   6746 		   (result_brand == NULL)) ? "" : result_brand);
   6747 
   6748 	}
   6749 	break;
   6750       case 1:
   6751       case 2:
   6752 	if (print_headers) {
   6753 	  if ('x' == libfmt) {
   6754 	    fprintf(where,
   6755 		    cpu_title,
   6756 		    local_cpu_method,
   6757 		    remote_cpu_method);
   6758 	  }
   6759 	  else {
   6760 	    fprintf(where,
   6761 		    cpu_title_tput,
   6762 		    format_units(),
   6763 		    local_cpu_method,
   6764 		    remote_cpu_method);
   6765 	  }
   6766 	}
   6767 
   6768 	fprintf(where,
   6769 		cpu_fmt_1_line_1,		/* the format string */
   6770 		lss_size,		/* local sendbuf size */
   6771 		lsr_size,
   6772 		req_size,		/* how large were the requests */
   6773 		rsp_size,		/* guess */
   6774 		elapsed_time,		/* how long was the test */
   6775 		thruput,
   6776 		local_cpu_utilization,	/* local cpu */
   6777 		remote_cpu_utilization,	/* remote cpu */
   6778 		local_service_demand,	/* local service demand */
   6779 		remote_service_demand,	/* remote service demand */
   6780 		((print_headers) ||
   6781 		 (result_brand == NULL)) ? "" : result_brand);
   6782 	fprintf(where,
   6783 		cpu_fmt_1_line_2,
   6784 		rss_size,
   6785 		rsr_size);
   6786 	break;
   6787       }
   6788     }
   6789     else {
   6790       /* The tester did not wish to measure service demand. */
   6791       switch (verbosity) {
   6792       case 0:
   6793 	fprintf(where,
   6794 		tput_fmt_0,
   6795 		thruput,
   6796 		((print_headers) ||
   6797 		 (result_brand == NULL)) ? "" : result_brand);
   6798 	break;
   6799       case 1:
   6800       case 2:
   6801 	if (print_headers) {
   6802 	  fprintf(where,
   6803 		  ('x' == libfmt) ? tput_title : tput_title_band,
   6804 		  format_units());
   6805 	}
   6806 
   6807 	fprintf(where,
   6808 		tput_fmt_1_line_1,	/* the format string */
   6809 		lss_size,
   6810 		lsr_size,
   6811 		req_size,		/* how large were the requests */
   6812 		rsp_size,		/* how large were the responses */
   6813 		elapsed_time, 		/* how long did it take */
   6814 		thruput,
   6815 		((print_headers) ||
   6816 		 (result_brand == NULL)) ? "" : result_brand);
   6817 	fprintf(where,
   6818 		tput_fmt_1_line_2,
   6819 		rss_size, 		/* remote recvbuf size */
   6820 		rsr_size);
   6821 
   6822 	break;
   6823       }
   6824     }
   6825 
   6826     /* it would be a good thing to include information about some of the */
   6827     /* other parameters that may have been set for this test, but at the */
   6828     /* moment, I do not wish to figure-out all the  formatting, so I will */
   6829     /* just put this comment here to help remind me that it is something */
   6830     /* that should be done at a later time. */
   6831 
   6832     /* how to handle the verbose information in the presence of */
   6833     /* confidence intervals is yet to be determined... raj 11/94 */
   6834 
   6835     if (verbosity > 1) {
   6836       /* The user wanted to know it all, so we will give it to him. */
   6837       /* This information will include as much as we can find about */
   6838       /* UDP statistics, the alignments of the sends and receives */
   6839       /* and all that sort of rot... */
   6840 
   6841 #ifdef WANT_HISTOGRAM
   6842       fprintf(where,"\nHistogram of request/reponse times.\n");
   6843       HIST_report(time_hist);
   6844 #endif /* WANT_HISTOGRAM */
   6845     }
   6846     fflush(where);
   6847   }
   6848 }
   6849 
   6850 
   6851 #endif /* WANT_MIGRATION */
   6852 
   6853 
   6854 /* using legacy test names will cause certain default settings to be
   6856    made before we scan the test-specific arguments.  raj 2010-07-20 */
   6857 static void
   6858 set_omni_defaults_by_legacy_testname() {
   6859 
   6860   /* the uber defaults are for a unidirectional test using TCP */
   6861   protocol = IPPROTO_TCP;
   6862   socket_type = SOCK_STREAM;
   6863   connection_test = 0;
   6864   req_size = rsp_size = -1;
   6865   was_legacy = 1;
   6866   legacy = 1;
   6867   implicit_direction = 0;  /* do we allow certain options to
   6868 			      implicitly affect the test direction? */
   6869   if (strcasecmp(test_name,"TCP_STREAM") == 0) {
   6870     direction = NETPERF_XMIT;
   6871   }
   6872   else if (strcasecmp(test_name,"TCP_MAERTS") == 0) {
   6873     direction = NETPERF_RECV;
   6874   }
   6875   else if (strcasecmp(test_name,"TCP_RR") == 0) {
   6876     req_size = rsp_size = 1;
   6877     direction = 0;
   6878     direction |= NETPERF_XMIT;
   6879     direction |= NETPERF_RECV;
   6880   }
   6881   else if (strcasecmp(test_name,"UDP_STREAM") == 0) {
   6882      protocol = IPPROTO_UDP;
   6883     socket_type = SOCK_DGRAM;
   6884   }
   6885   else if (strcasecmp(test_name,"UDP_RR") == 0) {
   6886      protocol = IPPROTO_UDP;
   6887     socket_type = SOCK_DGRAM;
   6888     direction = 0;
   6889     direction |= NETPERF_XMIT;
   6890     direction |= NETPERF_RECV;
   6891     req_size = rsp_size = 1;
   6892   }
   6893   else if (strcasecmp(test_name,"TCP_CC") == 0) {
   6894     direction = 0;
   6895     connection_test = 1;
   6896   }
   6897   else if (strcasecmp(test_name,"TCP_CRR") == 0) {
   6898     direction = 0;
   6899     direction |= NETPERF_XMIT;
   6900     direction |= NETPERF_RECV;
   6901     req_size = rsp_size = 1;
   6902     connection_test = 1;
   6903   }
   6904   else if (strcasecmp(test_name,"omni") == 0) {
   6905     /* there is not much to do here but clear the legacy flag */
   6906     was_legacy = 0;
   6907     legacy = 0;
   6908     implicit_direction = 1;
   6909   }
   6910   socket_type_str = hst_to_str(socket_type);
   6911 }
   6912 
   6913 char omni_usage[] = "\n\
   6914 Usage: netperf [global options] -- [test options] \n\
   6915 \n\
   6916 OMNI and Migrated BSD Sockets Test Options:\n\
   6917     -b number         Send number requests at start of _RR tests\n\
   6918     -c                Explicitly declare this a connection test such as\n\
   6919                       TCP_CRR or TCP_CC\n\
   6920     -C                Set TCP_CORK when available\n\
   6921     -d direction      Explicitly set test direction based on bitwise OR\n\
   6922                       of 0x2 for transmit and 0x4 for receive. Default:\n\
   6923                       based on test type\n\
   6924     -D [L][,R]        Set TCP_NODELAY locally and/or remotely (TCP_*)\n\
   6925     -h                Display this text\n\
   6926     -H name[/mask],fam  Use name (or IP) and family as target of data connection\n\
   6927                       A mask value will cause randomization of the IP used\n\
   6928     -k [file]         Generate keyval output optionally based on file\n\
   6929                       Use filename of '?' to get the list of choices\n\
   6930     -K loc[,rem]      Set the local and/or remote congestion control\n\
   6931                       algorithm to use on those platforms where it can\n\
   6932                       be set.\n\
   6933     -L name[/mask],fam  Use name (or IP) and family as source of data connection\n\
   6934                       A mask value will cause randomization of the IP used\n\
   6935     -m local,remote   Set the send size for _STREAM/_MAERTS tests\n\
   6936     -M local,remote   Set the recv size for _STREAM/_MAERTS tests\n\
   6937     -n                Use the connected socket for UDP locally\n\
   6938     -N                Use the connected socket for UDP remotely\n\
   6939     -o [file]         Generate CSV output optionally based on file\n\
   6940                       Use filename of '?' to get the list of choices\n\
   6941     -O [file]         Generate classic-style output based on file\n\
   6942                       Use filename of '?' to get the list of choices\n\
   6943     -p min[,max]      Set the min/max port numbers for TCP_CRR, TCP_TRR\n\
   6944     -P local[,remote] Set the local/remote port for the data socket\n\
   6945     -r req,[rsp]      Set request/response sizes (TCP_RR, UDP_RR)\n\
   6946     -R 0/1            Allow routing of traffic on data connection.\n\
   6947                       Default: 0 (off) for UDP_STREAM, 1 (on) otherwise\n\
   6948     -s send[,recv]    Set local socket send/recv buffer sizes\n\
   6949     -S send[,recv]    Set remote socket send/recv buffer sizes\n\
   6950     -t type           Explicitly set socket type. Default is implicit\n\
   6951                       based on other settings\n\
   6952     -T protocol       Explicitly set data connection protocol. Default is\n\
   6953                       implicit based on other settings\n\
   6954     -u uuid           Use the supplied string as the UUID for this test.\n\
   6955     -4                Use AF_INET (eg IPv4) on both ends of the data conn\n\
   6956     -6                Use AF_INET6 (eg IPv6) on both ends of the data conn\n\
   6957 \n\
   6958 For those options taking two parms, at least one must be specified;\n\
   6959 specifying one value without a comma will set both parms to that\n\
   6960 value, specifying a value with a leading comma will set just the second\n\
   6961 parm, a value with a trailing comma will set just the first. To set\n\
   6962 each parm to unique values, specify both and separate them with a\n\
   6963 comma.\n";
   6964 
   6965 void
   6966 print_omni_usage()
   6967 {
   6968 
   6969   fwrite(omni_usage, sizeof(char), strlen(omni_usage), stdout);
   6970   exit(1);
   6971 
   6972 }
   6973 
   6974 
   6975 void
   6977 scan_omni_args(int argc, char *argv[])
   6978 
   6979 {
   6980 
   6981 #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"
   6982 
   6983   extern char	*optarg;	  /* pointer to option string	*/
   6984 
   6985   int		c;
   6986   int           have_uuid = 0;
   6987   int           have_R_option = 0;
   6988 
   6989   char
   6990     arg1[BUFSIZ],  /* argument holders		*/
   6991     arg2[BUFSIZ],
   6992     arg3[BUFSIZ];
   6993 
   6994   if (debug) {
   6995     int i;
   6996     printf("%s called with the following argument vector\n",
   6997 	   __FUNCTION__);
   6998     for (i = 0; i< argc; i++) {
   6999       printf("%s ",argv[i]);
   7000     }
   7001     printf("\n");
   7002   }
   7003 
   7004   /* double-check struct sizes */
   7005   {
   7006     const union netperf_request_struct * u = (const union netperf_request_struct *)0;
   7007     if (debug) {
   7008       fprintf(where, "sizeof(omni_request_struct)=%d/%d\n",
   7009               (int)sizeof(struct omni_request_struct),
   7010               (int)sizeof(u->content.test_specific_data));
   7011       fprintf(where, "sizeof(omni_response_struct)=%d/%d\n",
   7012               (int)sizeof(struct omni_response_struct),
   7013               (int)sizeof(u->content.test_specific_data));
   7014       fprintf(where, "sizeof(omni_results_struct)=%d/%d\n",
   7015               (int)sizeof(struct omni_results_struct),
   7016               (int)sizeof(u->content.test_specific_data));
   7017     }
   7018     assert(sizeof(struct omni_request_struct)
   7019            <= sizeof(u->content.test_specific_data));
   7020     assert(sizeof(struct omni_response_struct)
   7021            <= sizeof(u->content.test_specific_data));
   7022     assert(sizeof(struct omni_results_struct)
   7023            <= sizeof(u->content.test_specific_data));
   7024   }
   7025 
   7026   strncpy(local_data_port,"0",sizeof(local_data_port));
   7027   strncpy(remote_data_port,"0",sizeof(remote_data_port));
   7028 
   7029   /* this will handle setting default settings based on test name */
   7030   set_omni_defaults_by_legacy_testname();
   7031 
   7032   /* Go through all the command line arguments and break them out. For
   7033      those options that take two parms, specifying only the first will
   7034      set both to that value. Specifying only the second will leave the
   7035      first untouched. To change only the first, use the form "first,"
   7036      (see the routine break_args.. */
   7037 
   7038   while ((c= getopt(argc, argv, OMNI_ARGS)) != EOF) {
   7039     switch (c) {
   7040     case '?':
   7041     case '4':
   7042       remote_data_family = AF_INET;
   7043       local_data_family = AF_INET;
   7044       break;
   7045     case '6':
   7046 #if defined(AF_INET6)
   7047       remote_data_family = AF_INET6;
   7048       local_data_family = AF_INET6;
   7049 #else
   7050       fprintf(stderr,
   7051 	      "This netperf was not compiled on an IPv6 capable host!\n");
   7052       fflush(stderr);
   7053       exit(-1);
   7054 #endif
   7055       break;
   7056     case 'h':
   7057       print_omni_usage();
   7058       exit(1);
   7059     case 'a':
   7060       want_defer_accept = 1;
   7061       break;
   7062     case 'B':
   7063       want_use_pktinfo = 1;
   7064       break;
   7065     case 'b':
   7066 #ifdef WANT_FIRST_BURST
   7067       first_burst_size = atoi(optarg);
   7068 #else /* WANT_FIRST_BURST */
   7069       printf("Initial request burst functionality not compiled-in!\n");
   7070 #endif /* WANT_FIRST_BURST */
   7071       break;
   7072     case 'c':
   7073       /* this is a connection test */
   7074       connection_test = 1;
   7075       break;
   7076     case 'C':
   7077 #ifdef TCP_CORK
   7078       /* set TCP_CORK */
   7079       loc_tcpcork = 1;
   7080       rem_tcpcork = 1; /* however, at first, we ony have cork affect loc */
   7081 #else
   7082       printf("WARNING: TCP_CORK not available on this platform!\n");
   7083 #endif /* TCP_CORK */
   7084       break;
   7085     case 'd':
   7086       /* arbitrarily set the direction variable, but only for an
   7087 	 actual omni test and then disable implicit setting of
   7088 	 direction */
   7089       if (!was_legacy) {
   7090 	direction = parse_direction(optarg);
   7091 	implicit_direction = 0;
   7092       }
   7093       break;
   7094     case 'D':
   7095       /* set the TCP nodelay flag */
   7096       loc_nodelay = 1;
   7097       rem_nodelay = 1;
   7098       break;
   7099     case 'F':
   7100 #if defined(MSG_FASTOPEN)
   7101       use_fastopen = 1;
   7102 #else
   7103       printf("WARNING: TCP FASTOPEN not available on this platform!\n");
   7104 #endif
   7105       break;
   7106     case 'e':
   7107       /* set the rEceive timeout */
   7108       receive_timeout = atoi(optarg);
   7109       break;
   7110     case 'g':
   7111       /* enable SO_DEBUG, or at least make the attempt, on the data socket */
   7112       socket_debug = 1;
   7113       break;
   7114     case 'G':
   7115       /* set the value for a tcp_maxseG call*/
   7116       transport_mss_req = atoi(optarg);
   7117       break;
   7118     case 'H':
   7119       break_args_explicit_sep(optarg,',',arg1,arg2);
   7120       if (arg1[0]) {
   7121 	/* check to see if there was a width, which we would want to
   7122 	   be arg3. for simplicities sake, we will assume the width
   7123 	   must follow the address and not the address family - ie
   7124 	   1.2.3.4/24,inet.  This means we can just pass optarg again
   7125 	   as the source rather than have to shuffle arg values. */
   7126 	break_args_explicit_sep(optarg,'/',arg1,arg3);
   7127 	if (arg1[0]) {
   7128 	  remote_data_address = malloc(strlen(arg1)+1);
   7129 	  strcpy(remote_data_address,arg1);
   7130 	  explicit_data_address = 1;
   7131 	}
   7132 	if (arg3[0]) {
   7133 	  remote_mask_len = convert(arg3);
   7134 	}
   7135       }
   7136       if (arg2[0]) {
   7137 	remote_data_family = parse_address_family(arg2);
   7138       }
   7139       break;
   7140     case 'i':
   7141       fprintf(stderr,"The support for check_interval has been removed because the contributing editor no longer knew what it was for\n");
   7142       fflush(stderr);
   7143       break;
   7144     case 'I':
   7145       use_write = 1;
   7146       break;
   7147     case 'j':
   7148       parallel_connections = atoi(optarg);
   7149       break;
   7150     case 'k':
   7151       netperf_output_mode = KEYVAL;
   7152       legacy = 0;
   7153       /* obliterate any previous file name */
   7154       if (output_selection_spec) {
   7155 	free(output_selection_spec);
   7156 	output_selection_spec = NULL;
   7157       }
   7158       if (argv[optind] && ((unsigned char)argv[optind][0] != '-')) {
   7159 	/* we assume that what follows is the name of a file with the
   7160 	   list of desired output values. */
   7161 	output_selection_spec = strdup(argv[optind]);
   7162 	optind++;
   7163 	/* special case - if the file name is "?" then we will emit a
   7164 	   list of the available outputs */
   7165 	if (strcmp(output_selection_spec,"?") == 0) {
   7166 	  dump_netperf_output_choices(stdout,1);
   7167 	  exit(1);
   7168 	}
   7169       }
   7170       break;
   7171     case 'K':
   7172       /* "Kongestion Kontrol */
   7173       break_args(optarg,arg1,arg2);
   7174       if (arg1[0])
   7175 	strncpy(local_cong_control_req,arg1,sizeof(local_cong_control_req));
   7176       if (arg2[2])
   7177 	strncpy(remote_cong_control_req,arg2,sizeof(remote_cong_control_req));
   7178       break;
   7179     case 'l':
   7180       multicast_ttl = atoi(optarg);
   7181       break;
   7182     case 'L':
   7183       break_args_explicit_sep(optarg,',',arg1,arg2);
   7184       if (arg1[0]) {
   7185 	/* check to see if there was a width, which we would want to
   7186 	   be arg3. for simplicities sake, we will assume the width
   7187 	   must follow the address and not the address family - ie
   7188 	   1.2.3.4/24,inet.  This means we can just pass optarg again
   7189 	   as the source rather than have to shuffle arg values. */
   7190 	break_args_explicit_sep(optarg,'/',arg1,arg3);
   7191 	if (arg1[0]) {
   7192 	  local_data_address = malloc(strlen(arg1)+1);
   7193 	  strcpy(local_data_address,arg1);
   7194 	}
   7195 	if (arg3[0]) {
   7196 	  local_mask_len = convert(arg3);
   7197 	}
   7198       }
   7199       if (arg2[0]) {
   7200 	local_data_family = parse_address_family(arg2);
   7201       }
   7202       break;
   7203     case 'm':
   7204       /* set the send size. if we set the local send size it will add
   7205 	 XMIT to direction.  if we set the remote send size it will
   7206 	 add RECV to the direction.  likely as not this will need some
   7207 	 additional throught */
   7208       break_args_explicit(optarg,arg1,arg2);
   7209       if (arg1[0]) {
   7210 	send_size = convert(arg1);
   7211 	if (implicit_direction)
   7212 	  direction |= NETPERF_XMIT;
   7213       }
   7214       if (arg2[0]) {
   7215 	remote_send_size_req = convert(arg2);
   7216 	if (implicit_direction)
   7217 	  direction |= NETPERF_RECV;
   7218       }
   7219       break;
   7220     case 'M':
   7221       /* set the recv sizes.  if we set the local recv size it will
   7222 	 add RECV to direction.  if we set the remote recv size it
   7223 	 will add XMIT to direction  */
   7224       break_args_explicit(optarg,arg1,arg2);
   7225       if (arg1[0]) {
   7226 	remote_recv_size_req = convert(arg1);
   7227 	if (implicit_direction)
   7228 	  direction |= NETPERF_XMIT;
   7229       }
   7230       if (arg2[0]) {
   7231 	recv_size = convert(arg2);
   7232 	if (implicit_direction)
   7233 	  direction |= NETPERF_RECV;
   7234       }
   7235       break;
   7236     case 'n':
   7237       /* set the local socket type */
   7238       local_connected = 1;
   7239       break;
   7240     case 'N':
   7241       /* set the remote socket type */
   7242       remote_connected = 1;
   7243       break;
   7244     case 'o':
   7245       netperf_output_mode = CSV;
   7246       legacy = 0;
   7247       /* obliterate any previous file name */
   7248       if (output_selection_spec) {
   7249 	free(output_selection_spec);
   7250 	output_selection_spec = NULL;
   7251       }
   7252       if (output_selection_spec) {
   7253 	free(output_selection_spec);
   7254 	output_selection_spec = NULL;
   7255       }
   7256       if (argv[optind] && ((unsigned char)argv[optind][0] != '-')) {
   7257 	/* we assume that what follows is the name of a file with the
   7258 	   list of desired output values. */
   7259 	output_selection_spec = strdup(argv[optind]);
   7260 	optind++;
   7261 	/* special case - if the file name is "?" then we will emit a
   7262 	   list of the available outputs */
   7263 	if (strcmp(output_selection_spec,"?") == 0) {
   7264 	  dump_netperf_output_choices(stdout,1);
   7265 	  exit(1);
   7266 	}
   7267       }
   7268       break;
   7269     case 'O':
   7270       netperf_output_mode = HUMAN;
   7271       legacy = 0;
   7272       /* obliterate any previous file name */
   7273       if (output_selection_spec) {
   7274 	free(output_selection_spec);
   7275 	output_selection_spec = NULL;
   7276       }
   7277       if (argv[optind] && ((unsigned char)argv[optind][0] != '-')) {
   7278 	/* we assume that what follows is the name of a file with the
   7279 	   list of desired output values */
   7280 	output_selection_spec = strdup(argv[optind]);
   7281 	optind++;
   7282 	if (strcmp(output_selection_spec,"?") == 0) {
   7283 	  dump_netperf_output_choices(stdout,0);
   7284 	  exit(1);
   7285 	}
   7286       }
   7287       break;
   7288     case 'p':
   7289       /* set the min and max port numbers for the TCP_CRR and TCP_TRR */
   7290       /* tests. */
   7291       break_args(optarg,arg1,arg2);
   7292       if (arg1[0])
   7293 	client_port_min = atoi(arg1);
   7294       if (arg2[0])
   7295 	client_port_max = atoi(arg2);
   7296       break;
   7297     case 'P':
   7298       /* set the local and remote data port numbers for the tests to
   7299 	 allow them to run through those blankety blank end-to-end
   7300 	 breaking firewalls. raj 2004-06-15 */
   7301       break_args(optarg,arg1,arg2);
   7302       if (arg1[0])
   7303 	strncpy(local_data_port,arg1,sizeof(local_data_port));
   7304       if (arg2[0])
   7305 	strncpy(remote_data_port,arg2,sizeof(remote_data_port));
   7306       break;
   7307     case 'r':
   7308       /* set the request/response sizes. setting request/response
   7309 	 sizes implicitly sets direction to XMIT and RECV */
   7310       if (implicit_direction) {
   7311 	direction |= NETPERF_XMIT;
   7312 	direction |= NETPERF_RECV;
   7313       }
   7314       break_args(optarg,arg1,arg2);
   7315       if (arg1[0])
   7316 	req_size = convert(arg1);
   7317       if (arg2[0])
   7318 	rsp_size = convert(arg2);
   7319       break;
   7320     case 'R':
   7321       routing_allowed = atoi(optarg);
   7322       have_R_option = 1;
   7323       break;
   7324     case 's':
   7325       /* set local socket sizes */
   7326       break_args(optarg,arg1,arg2);
   7327       if (arg1[0])
   7328 	lss_size_req = convert(arg1);
   7329       if (arg2[0])
   7330 	lsr_size_req = convert(arg2);
   7331       break;
   7332     case 'S':
   7333       /* set remote socket sizes */
   7334       break_args(optarg,arg1,arg2);
   7335       if (arg1[0])
   7336 	rss_size_req = convert(arg1);
   7337       if (arg2[0])
   7338 	rsr_size_req = convert(arg2);
   7339       break;
   7340     case 't':
   7341       /* set the socket type */
   7342       socket_type = parse_socket_type(optarg);
   7343       break;
   7344     case 'T':
   7345       /* set the protocol - aka "Transport" */
   7346       protocol = parse_protocol(optarg);
   7347       break;
   7348     case 'u':
   7349       /* use the supplied string as the UUID for this test. at some
   7350 	 point we may want to sanity check the string we are given but
   7351 	 for now we won't worry about it */
   7352       strncpy(test_uuid,optarg,sizeof(test_uuid));
   7353       /* strncpy may leave us with a string without a null at the end */
   7354       test_uuid[sizeof(test_uuid) - 1] = 0;
   7355       have_uuid = 1;
   7356       break;
   7357     case 'U':
   7358       /* we don't want to give-up on the failure of a connect() call */
   7359       dont_give_up = 1;
   7360       break;
   7361     case 'W':
   7362       /* set the "width" of the user space data */
   7363       /* buffer. This will be the number of */
   7364       /* send_size buffers malloc'd in the */
   7365       /* *_STREAM test. It may be enhanced to set */
   7366       /* both send and receive "widths" but for now */
   7367       /* it is just the sending *_STREAM. */
   7368       send_width = convert(optarg);
   7369       break;
   7370     case 'V' :
   7371       /* we want to do copy avoidance and will set */
   7372       /* it for everything, everywhere, if we really */
   7373       /* can. of course, we don't know anything */
   7374       /* about the remote... */
   7375       loc_sndavoid = 1;
   7376       loc_rcvavoid = 1;
   7377       rem_sndavoid = 1;
   7378       rem_rcvavoid = 1;
   7379       break;
   7380     };
   7381   }
   7382 
   7383   /* generate the UUID for this test if the user has not supplied it */
   7384   if (!have_uuid)
   7385     get_uuid_string(test_uuid,sizeof(test_uuid));
   7386 
   7387   protocol_str = protocol_to_str(protocol);
   7388   /* ok, if we have gone through all that, and direction is still
   7389      zero, let us see if it needs to be set to something else. */
   7390   if ((0 == direction) && (!connection_test)) direction = NETPERF_XMIT;
   7391   direction_str = direction_to_str(direction);
   7392 
   7393   /* to cover the backside of blithering idiots who run unidirectional
   7394      UDP tests on test setups where they might trash their corporate
   7395      WAN, we grudgingly provide a safety latch. unless explicitly
   7396      enabled, UDP_STREAM/UDP_MAERTS sockets will not allow themselves
   7397      to be routed via a gateway. raj 20091026 */
   7398 
   7399   if ((!have_R_option) &&
   7400       (protocol == IPPROTO_UDP) &&
   7401       (!NETPERF_IS_RR(direction))) {
   7402     routing_allowed = 0;
   7403   }
   7404 
   7405   /* some other sanity checks we need to make would include stuff when
   7406      the user has set -m and -M such that both XMIT and RECV are set
   7407      and has not set -r. initially we will not allow that.  at some
   7408      point we might allow that if the user has also set -r, but until
   7409      then the code will simply ignore the values from -m and -M when
   7410      -r is set. */
   7411 
   7412 #if defined(WANT_HISTOGRAM)
   7413   if (verbosity > 1) keep_histogram = 1;
   7414 #endif
   7415 
   7416   /* did the user use -d 6 but not set -r? */
   7417   if (NETPERF_IS_RR(direction) && !NETPERF_CC(direction)) {
   7418     if (req_size == -1)
   7419       req_size = 1;
   7420     if (rsp_size == -1)
   7421       rsp_size = 1;
   7422   }
   7423 
   7424   /* ok, time to sanity check the output units */
   7425   if ('?' == libfmt) {
   7426     /* if this is a RR test then set it to 'x' for transactions */
   7427     if (NETPERF_IS_RR(direction)) {
   7428       libfmt = 'x';
   7429     }
   7430     else {
   7431       libfmt = 'm';
   7432     }
   7433   }
   7434   else if ('x' == libfmt) {
   7435     /* now, a format of 'x' makes no sense for anything other than
   7436        an RR test. if someone has been silly enough to try to set
   7437        that, we will reset it silently to default - namely 'm' */
   7438     if (!NETPERF_IS_RR(direction)) {
   7439       libfmt = 'm';
   7440     }
   7441   }
   7442 
   7443   /* this needs to be strdup :) */
   7444   thruput_format_str = strdup(format_units());
   7445 
   7446   /* so, if there is to be no control connection, we want to have some
   7447      different settings for a few things */
   7448 
   7449   if (no_control) {
   7450     if (strcmp(remote_data_port,"0") == 0) {
   7451       /* we need to select either the discard port, echo port or
   7452 	 chargen port dedepending on the test direction. raj
   7453 	 20101220 */
   7454       if (NETPERF_XMIT_ONLY(direction)) {
   7455 	strncpy(remote_data_port,"discard",sizeof(remote_data_port));
   7456 	recv_size = -1;
   7457       }
   7458       else if (NETPERF_RECV_ONLY(direction)) {
   7459 	strncpy(remote_data_port,"chargen",sizeof(remote_data_port));
   7460 	send_size = -1;
   7461       }
   7462       else if (NETPERF_IS_RR(direction) || NETPERF_CC(direction)) {
   7463 	strncpy(remote_data_port,"echo",sizeof(remote_data_port));
   7464 	rsp_size = req_size;
   7465       }
   7466       else {
   7467 	printf("No default port known for the %s test, please set one yourself\n",test_name);
   7468 	exit(-1);
   7469       }
   7470     }
   7471     remote_data_port[sizeof(remote_data_port) - 1] = '\0';
   7472 
   7473     /* I go back and forth on whether these should become -1 or if
   7474        they should become 0 for a no_control test. what do you think?
   7475        raj 2006-02-08 */
   7476 
   7477     rem_rcvavoid = -1;
   7478     rem_sndavoid = -1;
   7479     rss_size_req = -1;
   7480     rsr_size_req = -1;
   7481     rem_nodelay = -1;
   7482 
   7483   }
   7484   /* so, did the user request a few things implicitly via output selection? */
   7485   if (!legacy)
   7486     print_omni_init();
   7487 
   7488   if (desired_output_groups & OMNI_WANT_STATS) {
   7489     keep_statistics = 1;
   7490     keep_histogram = 1;
   7491   }
   7492 
   7493 }
   7494 
   7495 #endif /* WANT_OMNI */
   7496