1 /*---------------------------------------------------------------
2 * Copyright (c) 1999,2000,2001,2002,2003
3 * The Board of Trustees of the University of Illinois
5 *---------------------------------------------------------------
6 * Permission is hereby granted, free of charge, to any person
7 * obtaining a copy of this software (Iperf) and associated
8 * documentation files (the "Software"), to deal in the Software
9 * without restriction, including without limitation the
10 * rights to use, copy, modify, merge, publish, distribute,
11 * sublicense, and/or sell copies of the Software, and to permit
12 * persons to whom the Software is furnished to do
13 * so, subject to the following conditions:
16 * Redistributions of source code must retain the above
17 * copyright notice, this list of conditions and
18 * the following disclaimers.
21 * Redistributions in binary form must reproduce the above
22 * copyright notice, this list of conditions and the following
23 * disclaimers in the documentation and/or other materials
24 * provided with the distribution.
27 * Neither the names of the University of Illinois, NCSA,
28 * nor the names of its contributors may be used to endorse
29 * or promote products derived from this Software without
30 * specific prior written permission.
32 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
33 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
34 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
35 * NONINFRINGEMENT. IN NO EVENT SHALL THE CONTIBUTORS OR COPYRIGHT
36 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
37 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
38 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE
39 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
40 * ________________________________________________________________
41 * National Laboratory for Applied Network Research
42 * National Center for Supercomputing Applications
43 * University of Illinois at Urbana-Champaign
44 * http://www.ncsa.uiuc.edu
45 * ________________________________________________________________
48 * by Kevin Gibbs <kgibbs@nlanr.net>
50 * ________________________________________________________________ */
53 #include "Settings.hpp"
56 #include "report_default.h"
59 #include "PerfSocket.hpp"
60 #include "SocketAddr.h"
67 * Prints transfer reports in default style
69 void reporter_printstats( Transfer_Info *stats ) {
71 byte_snprintf( buffer, sizeof(buffer)/2, (double) stats->TotalLen,
72 toupper( stats->mFormat));
73 byte_snprintf( &buffer[sizeof(buffer)/2], sizeof(buffer)/2,
74 stats->TotalLen / (stats->endTime - stats->startTime),
77 if ( stats->mUDP != (char)kMode_Server ) {
79 printf( report_bw_format, stats->transferID,
80 stats->startTime, stats->endTime,
81 buffer, &buffer[sizeof(buffer)/2] );
84 printf( report_bw_jitter_loss_format, stats->transferID,
85 stats->startTime, stats->endTime,
86 buffer, &buffer[sizeof(buffer)/2],
87 stats->jitter*1000.0, stats->cntError, stats->cntDatagrams,
88 (100.0 * stats->cntError) / stats->cntDatagrams );
89 if ( stats->cntOutofOrder > 0 ) {
90 printf( report_outoforder,
91 stats->transferID, stats->startTime,
92 stats->endTime, stats->cntOutofOrder );
95 if ( stats->free == 1 && stats->mUDP == (char)kMode_Client ) {
96 printf( report_datagrams, stats->transferID, stats->cntDatagrams );
102 * Prints multiple transfer reports in default style
104 void reporter_multistats( Transfer_Info *stats ) {
106 byte_snprintf( buffer, sizeof(buffer)/2, (double) stats->TotalLen,
107 toupper( stats->mFormat));
108 byte_snprintf( &buffer[sizeof(buffer)/2], sizeof(buffer)/2,
109 stats->TotalLen / (stats->endTime - stats->startTime),
112 if ( stats->mUDP != (char)kMode_Server ) {
113 // TCP-like Reporting
114 printf( report_sum_bw_format,
115 stats->startTime, stats->endTime,
116 buffer, &buffer[sizeof(buffer)/2] );
118 // UDP-like Reporting
119 printf( report_sum_bw_jitter_loss_format,
120 stats->startTime, stats->endTime,
121 buffer, &buffer[sizeof(buffer)/2],
122 stats->jitter*1000.0, stats->cntError, stats->cntDatagrams,
123 (100.0 * stats->cntError) / stats->cntDatagrams );
124 if ( stats->cntOutofOrder > 0 ) {
125 printf( report_sum_outoforder,
127 stats->endTime, stats->cntOutofOrder );
130 if ( stats->free == 1 && stats->mUDP == (char)kMode_Client ) {
131 printf( report_sum_datagrams, stats->cntDatagrams );
136 * Prints server transfer reports in default style
138 void reporter_serverstats( Connection_Info *nused, Transfer_Info *stats ) {
139 printf( server_reporting, stats->transferID );
140 reporter_printstats( stats );
143 static char *McastIface(const unsigned if_index)
145 static char ifnam[IF_NAMESIZE];
148 return "default interface";
149 if (if_indextoname(if_index, ifnam))
151 return "unknown interface";
155 * Report the client or listener Settings in default style
157 void reporter_reportsettings( ReporterData *data ) {
158 int win, win_requested;
160 win = get_buffer_sock_size(data->info.transferID,
161 data->mThreadMode != kMode_Listener);
162 win_requested = data->mWinSize;
164 printf( seperator_line );
165 if ( data->mThreadMode == kMode_Listener ) {
167 protoName(data->mProtocol),
172 protoName(data->mProtocol),
175 if ( data->mLocalhost != NULL ) {
176 if (SockAddr_isMulticast((struct sockaddr *)&data->connection.local))
177 printf(join_multicast, data->mLocalhost, McastIface(data->mMcastIface));
179 printf(bind_address, data->mLocalhost);
182 if ( isPacketOriented( data ) ) {
183 printf( (data->mThreadMode == kMode_Listener ?
184 server_datagram_size : client_datagram_size),
186 if (SockAddr_isMulticast((struct sockaddr *)&data->connection.peer))
187 printf( multicast_ttl, data->info.mTTL);
188 } else if (data->mProtocol == kProto_DCCP)
189 printf("NOTE: running in bytestream-mode (maximum speed)\n");
191 byte_snprintf( buffer, sizeof(buffer), win,
192 toupper( data->info.mFormat));
194 if (data->mProtocol == kProto_TCP)
195 printf( "%s: %s", tcp_window_size, buffer);
197 printf( "%s %s: %s", protoName(data->mProtocol), dgram_buffer_size, buffer);
199 if ( win_requested == 0 ) {
200 printf( " %s", window_default );
201 } else if ( win != win_requested ) {
202 byte_snprintf( buffer, sizeof(buffer), win_requested,
203 toupper( data->info.mFormat));
204 printf( warn_window_requested, buffer );
208 if (data->mProtocol == kProto_TCP) {
209 char *cong_requested = data->info.congAlgo,
211 Socklen_t len = sizeof(cong);
213 if (getsockopt(data->info.transferID, IPPROTO_TCP, TCP_CONGESTION, cong, &len) < 0) {
214 fprintf(stderr, "WARNING: cannot determine TCP congestion control algorithm (err: %d %s)\n",
215 errno, strerror(errno));
217 printf("TCP congestion control algorithm: %s", cong[0] == '\0' ? "default" : cong);
219 if (data->info.congAlgo && strcmp(cong, data->info.congAlgo))
220 printf(" (NOT \"%s\"!)", data->info.congAlgo);
225 printf( seperator_line );
229 * Report a socket's peer IP address in default style
231 void *reporter_reportpeer(Connection_Info *stats, int ID)
234 char laddr[REPORT_ADDRLEN],
235 daddr[REPORT_ADDRLEN];
236 unsigned lport = SockAddr_port(&stats->local),
237 dport = SockAddr_port(&stats->peer);
239 SockAddr_name(&stats->local, laddr, sizeof(laddr));
240 SockAddr_name(&stats->peer, daddr, sizeof(daddr));
241 printf(report_peer, ID, laddr, lport, daddr, dport);
246 /* -------------------------------------------------------------------
247 * Report the MSS and MTU, given the MSS (or a guess thereof)
248 * ------------------------------------------------------------------- */
250 // compare the MSS against the (MTU - 40) to (MTU - 80) bytes.
251 // 40 byte IP header and somewhat arbitrarily, 40 more bytes of IP options.
253 #define checkMSS_MTU( inMSS, inMTU ) (inMTU-40) >= inMSS && inMSS >= (inMTU-80)
255 void reporter_reportMSS( int inMSS, thread_Settings *inSettings ) {
257 printf( report_mss_unsupported, inSettings->mSock );
262 if ( checkMSS_MTU( inMSS, 1500 ) ) {
265 } else if ( checkMSS_MTU( inMSS, 4352 ) ) {
268 } else if ( checkMSS_MTU( inMSS, 9180 ) ) {
271 } else if ( checkMSS_MTU( inMSS, 65280 ) ) {
274 } else if ( checkMSS_MTU( inMSS, 576 ) ) {
277 printf( warn_no_pathmtu );
280 net = "unknown interface";
284 inSettings->mSock, inMSS, mtu, net );
290 } /* end extern "C" */