]> sjero.net Git - iperf/blob - src/ReportDefault.c
DCCP support for iperf
[iperf] / src / ReportDefault.c
1 /*--------------------------------------------------------------- 
2  * Copyright (c) 1999,2000,2001,2002,2003                              
3  * The Board of Trustees of the University of Illinois            
4  * All Rights Reserved.                                           
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: 
14  *
15  *     
16  * Redistributions of source code must retain the above 
17  * copyright notice, this list of conditions and 
18  * the following disclaimers. 
19  *
20  *     
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. 
25  * 
26  *     
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. 
31  * 
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  * ________________________________________________________________ 
46  *
47  * ReportDefault.c
48  * by Kevin Gibbs <kgibbs@nlanr.net>
49  *
50  * ________________________________________________________________ */
51
52 #include "headers.h"
53 #include "Settings.hpp"
54 #include "util.h"
55 #include "Reporter.h"
56 #include "report_default.h"
57 #include "Thread.h"
58 #include "Locale.h"
59 #include "PerfSocket.hpp"
60 #include "SocketAddr.h"
61
62 #ifdef __cplusplus
63 extern "C" {
64 #endif
65
66 /*
67  * Prints transfer reports in default style
68  */
69 void reporter_printstats( Transfer_Info *stats ) {
70
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), 
75                    stats->mFormat);
76
77     if ( stats->mUDP != (char)kMode_Server ) {
78         // TCP-like Reporting
79         printf( report_bw_format, stats->transferID, 
80                 stats->startTime, stats->endTime, 
81                 buffer, &buffer[sizeof(buffer)/2] );
82     } else {
83         // UDP-like Reporting
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 );
93         }
94     }
95     if ( stats->free == 1 && stats->mUDP == (char)kMode_Client ) {
96         printf( report_datagrams, stats->transferID, stats->cntDatagrams ); 
97     }
98 }
99
100
101 /*
102  * Prints multiple transfer reports in default style
103  */
104 void reporter_multistats( Transfer_Info *stats ) {
105
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), 
110                    stats->mFormat);
111
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] );
117     } else {
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,
126                     stats->startTime, 
127                     stats->endTime, stats->cntOutofOrder );
128         }
129     }
130     if ( stats->free == 1 && stats->mUDP == (char)kMode_Client ) {
131         printf( report_sum_datagrams, stats->cntDatagrams ); 
132     }
133 }
134
135 /*
136  * Prints server transfer reports in default style
137  */
138 void reporter_serverstats( Connection_Info *nused, Transfer_Info *stats ) {
139     printf( server_reporting, stats->transferID );
140     reporter_printstats( stats );
141 }
142
143 /*
144  * Report the client or listener Settings in default style
145  */
146 void reporter_reportsettings( ReporterData *data ) {
147     int win, win_requested;
148
149     win = get_buffer_sock_size(data->info.transferID,
150                                data->mThreadMode != kMode_Listener);
151     win_requested = data->mWinSize;
152
153     printf( seperator_line );
154     if ( data->mThreadMode == kMode_Listener ) {
155         printf( server_port,
156                 protoName(data->mProtocol),
157                 data->mPort );
158     } else {
159         printf( client_port,
160                 data->mHost,
161                 protoName(data->mProtocol),
162                 data->mPort );
163     }
164     if ( data->mLocalhost != NULL ) {
165         printf( bind_address, data->mLocalhost );
166         if ( SockAddr_isMulticast( &data->connection.local ) ) {
167             printf( join_multicast, data->mLocalhost );
168         }
169     }
170
171     if ( isPacketOriented( data ) ) {
172         printf( (data->mThreadMode == kMode_Listener ? 
173                  server_datagram_size : client_datagram_size),
174                 data->mBufLen );
175         if ( SockAddr_isMulticast( &data->connection.peer ) ) {
176             printf( multicast_ttl, data->info.mTTL);
177         }
178     } else if (data->mProtocol == kProto_DCCP)
179             printf("NOTE: running in bytestream-mode (maximum speed)\n");
180
181     byte_snprintf( buffer, sizeof(buffer), win,
182                    toupper( data->info.mFormat));
183
184     if (data->mProtocol == kProto_TCP)
185         printf( "%s: %s",  tcp_window_size, buffer);
186     else
187         printf( "%s %s: %s", protoName(data->mProtocol), dgram_buffer_size, buffer);
188
189     if ( win_requested == 0 ) {
190         printf( " %s", window_default );
191     } else if ( win != win_requested ) {
192         byte_snprintf( buffer, sizeof(buffer), win_requested,
193                        toupper( data->info.mFormat));
194         printf( warn_window_requested, buffer );
195     }
196     printf( "\n" );
197     printf( seperator_line );
198 }
199
200 /*
201  * Report a socket's peer IP address in default style
202  */
203 void *reporter_reportpeer( Connection_Info *stats, int ID ) {
204     if ( ID > 0 ) {
205         // copy the inet_ntop into temp buffers, to avoid overwriting
206         char local_addr[ REPORT_ADDRLEN ];
207         char remote_addr[ REPORT_ADDRLEN ];
208         struct sockaddr *local = ((struct sockaddr*)&stats->local);
209         struct sockaddr *peer = ((struct sockaddr*)&stats->peer);
210     
211         if ( local->sa_family == AF_INET ) {
212             inet_ntop( AF_INET, &((struct sockaddr_in*)local)->sin_addr, 
213                        local_addr, REPORT_ADDRLEN);
214         }
215 #ifdef HAVE_IPV6
216           else {
217             inet_ntop( AF_INET6, &((struct sockaddr_in6*)local)->sin6_addr, 
218                        local_addr, REPORT_ADDRLEN);
219         }
220 #endif
221     
222         if ( peer->sa_family == AF_INET ) {
223             inet_ntop( AF_INET, &((struct sockaddr_in*)peer)->sin_addr, 
224                        remote_addr, REPORT_ADDRLEN);
225         }
226 #ifdef HAVE_IPV6
227           else {
228             inet_ntop( AF_INET6, &((struct sockaddr_in6*)peer)->sin6_addr, 
229                        remote_addr, REPORT_ADDRLEN);
230         }
231 #endif
232     
233         printf( report_peer,
234                 ID,
235                 local_addr,  ( local->sa_family == AF_INET ?
236                               ntohs(((struct sockaddr_in*)local)->sin_port) :
237 #ifdef HAVE_IPV6
238                               ntohs(((struct sockaddr_in6*)local)->sin6_port)),
239 #else
240                               0),
241 #endif
242                 remote_addr, ( peer->sa_family == AF_INET ?
243                               ntohs(((struct sockaddr_in*)peer)->sin_port) :
244 #ifdef HAVE_IPV6
245                               ntohs(((struct sockaddr_in6*)peer)->sin6_port)));
246 #else
247                               0));
248 #endif
249     }
250     return NULL;
251 }
252 // end ReportPeer
253
254 /* -------------------------------------------------------------------
255  * Report the MSS and MTU, given the MSS (or a guess thereof)
256  * ------------------------------------------------------------------- */
257
258 // compare the MSS against the (MTU - 40) to (MTU - 80) bytes.
259 // 40 byte IP header and somewhat arbitrarily, 40 more bytes of IP options.
260
261 #define checkMSS_MTU( inMSS, inMTU ) (inMTU-40) >= inMSS  &&  inMSS >= (inMTU-80)
262
263 void reporter_reportMSS( int inMSS, thread_Settings *inSettings ) {
264     if ( inMSS <= 0 ) {
265         printf( report_mss_unsupported, inSettings->mSock );
266     } else {
267         char* net;
268         int mtu = 0;
269
270         if ( checkMSS_MTU( inMSS, 1500 ) ) {
271             net = "ethernet";
272             mtu = 1500;
273         } else if ( checkMSS_MTU( inMSS, 4352 ) ) {
274             net = "FDDI";
275             mtu = 4352;
276         } else if ( checkMSS_MTU( inMSS, 9180 ) ) {
277             net = "ATM";
278             mtu = 9180;
279         } else if ( checkMSS_MTU( inMSS, 65280 ) ) {
280             net = "HIPPI";
281             mtu = 65280;
282         } else if ( checkMSS_MTU( inMSS, 576 ) ) {
283             net = "minimum";
284             mtu = 576;
285             printf( warn_no_pathmtu );
286         } else {
287             mtu = inMSS + 40;
288             net = "unknown interface";
289         }
290
291         printf( report_mss,
292                 inSettings->mSock, inMSS, mtu, net );
293     }
294 }
295 // end ReportMSS
296
297 #ifdef __cplusplus
298 } /* end extern "C" */
299 #endif