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 ) {
114 printf( report_sum_bw_format,
115 stats->startTime, stats->endTime,
116 buffer, &buffer[sizeof(buffer)/2] );
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 );
144 * Report the client or listener Settings in default style
146 void reporter_reportsettings( ReporterData *data ) {
147 int win, win_requested;
149 win = getsock_tcp_windowsize( data->info.transferID,
150 (data->mThreadMode == kMode_Listener ? 0 : 1) );
151 win_requested = data->mTCPWin;
153 printf( seperator_line );
154 if ( data->mThreadMode == kMode_Listener ) {
156 (isUDP( data ) ? "UDP" : "TCP"),
161 (isUDP( data ) ? "UDP" : "TCP"),
164 if ( data->mLocalhost != NULL ) {
165 printf( bind_address, data->mLocalhost );
166 if ( SockAddr_isMulticast( &data->connection.local ) ) {
167 printf( join_multicast, data->mLocalhost );
171 if ( isUDP( data ) ) {
172 printf( (data->mThreadMode == kMode_Listener ?
173 server_datagram_size : client_datagram_size),
175 if ( SockAddr_isMulticast( &data->connection.peer ) ) {
176 printf( multicast_ttl, data->info.mTTL);
179 byte_snprintf( buffer, sizeof(buffer), win,
180 toupper( data->info.mFormat));
181 printf( "%s: %s", (isUDP( data ) ?
182 udp_buffer_size : tcp_window_size), buffer );
184 if ( win_requested == 0 ) {
185 printf( " %s", window_default );
186 } else if ( win != win_requested ) {
187 byte_snprintf( buffer, sizeof(buffer), win_requested,
188 toupper( data->info.mFormat));
189 printf( warn_window_requested, buffer );
192 printf( seperator_line );
196 * Report a socket's peer IP address in default style
198 void *reporter_reportpeer( Connection_Info *stats, int ID ) {
200 // copy the inet_ntop into temp buffers, to avoid overwriting
201 char local_addr[ REPORT_ADDRLEN ];
202 char remote_addr[ REPORT_ADDRLEN ];
203 struct sockaddr *local = ((struct sockaddr*)&stats->local);
204 struct sockaddr *peer = ((struct sockaddr*)&stats->peer);
206 if ( local->sa_family == AF_INET ) {
207 inet_ntop( AF_INET, &((struct sockaddr_in*)local)->sin_addr,
208 local_addr, REPORT_ADDRLEN);
212 inet_ntop( AF_INET6, &((struct sockaddr_in6*)local)->sin6_addr,
213 local_addr, REPORT_ADDRLEN);
217 if ( peer->sa_family == AF_INET ) {
218 inet_ntop( AF_INET, &((struct sockaddr_in*)peer)->sin_addr,
219 remote_addr, REPORT_ADDRLEN);
223 inet_ntop( AF_INET6, &((struct sockaddr_in6*)peer)->sin6_addr,
224 remote_addr, REPORT_ADDRLEN);
230 local_addr, ( local->sa_family == AF_INET ?
231 ntohs(((struct sockaddr_in*)local)->sin_port) :
233 ntohs(((struct sockaddr_in6*)local)->sin6_port)),
237 remote_addr, ( peer->sa_family == AF_INET ?
238 ntohs(((struct sockaddr_in*)peer)->sin_port) :
240 ntohs(((struct sockaddr_in6*)peer)->sin6_port)));
249 /* -------------------------------------------------------------------
250 * Report the MSS and MTU, given the MSS (or a guess thereof)
251 * ------------------------------------------------------------------- */
253 // compare the MSS against the (MTU - 40) to (MTU - 80) bytes.
254 // 40 byte IP header and somewhat arbitrarily, 40 more bytes of IP options.
256 #define checkMSS_MTU( inMSS, inMTU ) (inMTU-40) >= inMSS && inMSS >= (inMTU-80)
258 void reporter_reportMSS( int inMSS, thread_Settings *inSettings ) {
260 printf( report_mss_unsupported, inSettings->mSock );
265 if ( checkMSS_MTU( inMSS, 1500 ) ) {
268 } else if ( checkMSS_MTU( inMSS, 4352 ) ) {
271 } else if ( checkMSS_MTU( inMSS, 9180 ) ) {
274 } else if ( checkMSS_MTU( inMSS, 65280 ) ) {
277 } else if ( checkMSS_MTU( inMSS, 576 ) ) {
280 printf( warn_no_pathmtu );
283 net = "unknown interface";
287 inSettings->mSock, inMSS, mtu, net );
293 } /* end extern "C" */