File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / iperf / src / tcp_info.c
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Sep 27 11:14:54 2023 UTC (18 months, 2 weeks ago) by misho
Branches: iperf, MAIN
CVS tags: v3_15, HEAD
Version 3.15

    1: /*
    2:  * iperf, Copyright (c) 2014, 2017, The Regents of the University of
    3:  * California, through Lawrence Berkeley National Laboratory (subject
    4:  * to receipt of any required approvals from the U.S. Dept. of
    5:  * Energy).  All rights reserved.
    6:  *
    7:  * If you have questions about your rights to use or distribute this
    8:  * software, please contact Berkeley Lab's Technology Transfer
    9:  * Department at TTD@lbl.gov.
   10:  *
   11:  * NOTICE.  This software is owned by the U.S. Department of Energy.
   12:  * As such, the U.S. Government has been granted for itself and others
   13:  * acting on its behalf a paid-up, nonexclusive, irrevocable,
   14:  * worldwide license in the Software to reproduce, prepare derivative
   15:  * works, and perform publicly and display publicly.  Beginning five
   16:  * (5) years after the date permission to assert copyright is obtained
   17:  * from the U.S. Department of Energy, and subject to any subsequent
   18:  * five (5) year renewals, the U.S. Government is granted for itself
   19:  * and others acting on its behalf a paid-up, nonexclusive,
   20:  * irrevocable, worldwide license in the Software to reproduce,
   21:  * prepare derivative works, distribute copies to the public, perform
   22:  * publicly and display publicly, and to permit others to do so.
   23:  *
   24:  * This code is distributed under a BSD style license, see the LICENSE
   25:  * file for complete information.
   26:  */
   27: 
   28: /*
   29:  * routines related to collection TCP_INFO using getsockopt()
   30:  *
   31:  * Brian Tierney, ESnet  (bltierney@es.net)
   32:  *
   33:  * Note that this is only really useful on Linux.
   34:  * XXX: only standard on linux versions 2.4 and later
   35:  #
   36:  * FreeBSD has a limited implementation that only includes the following:
   37:  *   tcpi_snd_ssthresh, tcpi_snd_cwnd, tcpi_rcv_space, tcpi_rtt
   38:  * Based on information on http://wiki.freebsd.org/8.0TODO, I dont think this will be
   39:  * fixed before v8.1 at the earliest.
   40:  *
   41:  * OSX has no support.
   42:  *
   43:  * I think MS Windows does support TCP_INFO, but iperf3 does not currently support Windows.
   44:  */
   45: 
   46: #include <stdio.h>
   47: #include <stdlib.h>
   48: #include <sys/param.h>
   49: #include <sys/types.h>
   50: #include <sys/socket.h>
   51: #include <string.h>
   52: #include <netinet/in.h>
   53: #include <errno.h>
   54: 
   55: #include "iperf.h"
   56: #include "iperf_api.h"
   57: #include "iperf_locale.h"
   58: 
   59: /*************************************************************/
   60: int
   61: has_tcpinfo(void)
   62: {
   63: #if (defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)) \
   64: 	&& defined(TCP_INFO)
   65:     return 1;
   66: #else
   67:     return 0;
   68: #endif
   69: }
   70: 
   71: /*************************************************************/
   72: int
   73: has_tcpinfo_retransmits(void)
   74: {
   75: #if defined(linux) && defined(TCP_MD5SIG)
   76:     /* TCP_MD5SIG doesn't actually have anything to do with TCP
   77:     ** retransmits, it just showed up in the same rev of the header
   78:     ** file.  If it's present then struct tcp_info has the
   79:     ** tcpi_total_retrans field that we need; if not, not.
   80:     */
   81:     return 1;
   82: #else
   83: #if defined(__FreeBSD__) && __FreeBSD_version >= 600000
   84:     return 1; /* Should work now */
   85: #elif (defined(__NetBSD__) || defined(__OpenBSD__)) && defined(TCP_INFO)
   86:     return 1;
   87: #else
   88:     return 0;
   89: #endif
   90: #endif
   91: }
   92: 
   93: /*************************************************************/
   94: void
   95: save_tcpinfo(struct iperf_stream *sp, struct iperf_interval_results *irp)
   96: {
   97: #if (defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)) && \
   98: 	defined(TCP_INFO)
   99:     socklen_t tcp_info_length = sizeof(struct tcp_info);
  100: 
  101:     if (getsockopt(sp->socket, IPPROTO_TCP, TCP_INFO, (void *)&irp->tcpInfo, &tcp_info_length) < 0)
  102: 	iperf_err(sp->test, "getsockopt - %s", strerror(errno));
  103: 
  104:     if (sp->test->debug) {
  105: 	printf("tcpi_snd_cwnd %u tcpi_snd_mss %u tcpi_rtt %u\n",
  106: 	       irp->tcpInfo.tcpi_snd_cwnd, irp->tcpInfo.tcpi_snd_mss,
  107: 	       irp->tcpInfo.tcpi_rtt);
  108:     }
  109: 
  110: #endif
  111: }
  112: 
  113: /*************************************************************/
  114: long
  115: get_total_retransmits(struct iperf_interval_results *irp)
  116: {
  117: #if defined(linux) && defined(TCP_MD5SIG)
  118:     return irp->tcpInfo.tcpi_total_retrans;
  119: #elif defined(__FreeBSD__) && __FreeBSD_version >= 600000
  120:     return irp->tcpInfo.tcpi_snd_rexmitpack;
  121: #elif (defined(__NetBSD__) || defined(__OpenBSD__)) && defined(TCP_INFO)
  122:     return irp->tcpInfo.tcpi_snd_rexmitpack;
  123: #else
  124:     return -1;
  125: #endif
  126: }
  127: 
  128: /*************************************************************/
  129: /*
  130:  * Return snd_cwnd in octets.
  131:  */
  132: long
  133: get_snd_cwnd(struct iperf_interval_results *irp)
  134: {
  135: #if defined(linux) && defined(TCP_MD5SIG)
  136:     return (long)irp->tcpInfo.tcpi_snd_cwnd * irp->tcpInfo.tcpi_snd_mss;
  137: #elif defined(__FreeBSD__) && __FreeBSD_version >= 600000
  138:     return irp->tcpInfo.tcpi_snd_cwnd;
  139: #elif defined(__NetBSD__) && defined(TCP_INFO)
  140:     return (long)irp->tcpInfo.tcpi_snd_cwnd * irp->tcpInfo.tcpi_snd_mss;
  141: #elif defined(__OpenBSD__) && defined(TCP_INFO)
  142:     return irp->tcpInfo.tcpi_snd_cwnd;
  143: #else
  144:     return -1;
  145: #endif
  146: }
  147: 
  148: /*************************************************************/
  149: /*
  150:  * Return snd_wnd in octets.
  151:  */
  152: long
  153: get_snd_wnd(struct iperf_interval_results *irp)
  154: {
  155: #if !defined(HAVE_TCP_INFO_SND_WND)
  156:     return -1;
  157: #elif defined(linux) && defined(TCP_MD5SIG)
  158:     return irp->tcpInfo.tcpi_snd_wnd;
  159: #elif defined(__FreeBSD__) && __FreeBSD_version >= 600000
  160:     return irp->tcpInfo.tcpi_snd_wnd;
  161: #elif defined(__NetBSD__) && defined(TCP_INFO)
  162:     return (long)irp->tcpInfo.tcpi_snd_wnd * irp->tcpInfo.tcpi_snd_mss;
  163: #elif defined(__OpenBSD__) && defined(TCP_INFO)
  164:     return irp->tcpInfo.tcpi_snd_wnd;
  165: #else
  166:     return -1;
  167: #endif
  168: }
  169: 
  170: /*************************************************************/
  171: /*
  172:  * Return rtt in usec.
  173:  */
  174: long
  175: get_rtt(struct iperf_interval_results *irp)
  176: {
  177: #if defined(linux) && defined(TCP_MD5SIG)
  178:     return irp->tcpInfo.tcpi_rtt;
  179: #elif defined(__FreeBSD__) && __FreeBSD_version >= 600000
  180:     return irp->tcpInfo.tcpi_rtt;
  181: #elif (defined(__NetBSD__) || defined(__OpenBSD__)) && defined(TCP_INFO)
  182:     return irp->tcpInfo.tcpi_rtt;
  183: #else
  184:     return -1;
  185: #endif
  186: }
  187: 
  188: /*************************************************************/
  189: /*
  190:  * Return rttvar in usec.
  191:  */
  192: long
  193: get_rttvar(struct iperf_interval_results *irp)
  194: {
  195: #if defined(linux) && defined(TCP_MD5SIG)
  196:     return irp->tcpInfo.tcpi_rttvar;
  197: #elif defined(__FreeBSD__) && __FreeBSD_version >= 600000
  198:     return irp->tcpInfo.tcpi_rttvar;
  199: #elif (defined(__NetBSD__) || defined(__OpenBSD__)) && defined(TCP_INFO)
  200:     return irp->tcpInfo.tcpi_rttvar;
  201: #else
  202:     return -1;
  203: #endif
  204: }
  205: 
  206: /*************************************************************/
  207: /*
  208:  * Return PMTU in bytes.
  209:  */
  210: long
  211: get_pmtu(struct iperf_interval_results *irp)
  212: {
  213: #if defined(linux) && defined(TCP_MD5SIG)
  214:     return irp->tcpInfo.tcpi_pmtu;
  215: #else
  216:     return -1;
  217: #endif
  218: }
  219: 
  220: /*************************************************************/
  221: void
  222: build_tcpinfo_message(struct iperf_interval_results *r, char *message)
  223: {
  224: #if defined(linux) && defined(TCP_INFO)
  225:     sprintf(message, report_tcpInfo, r->tcpInfo.tcpi_snd_cwnd, r->tcpInfo.tcpi_snd_ssthresh,
  226: 	    r->tcpInfo.tcpi_rcv_ssthresh, r->tcpInfo.tcpi_unacked, r->tcpInfo.tcpi_sacked,
  227: 	    r->tcpInfo.tcpi_lost, r->tcpInfo.tcpi_retrans, r->tcpInfo.tcpi_fackets,
  228: 	    r->tcpInfo.tcpi_rtt, r->tcpInfo.tcpi_reordering);
  229: #endif
  230: #if (defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)) && defined(TCP_INFO)
  231:     sprintf(message, report_tcpInfo, r->tcpInfo.tcpi_snd_cwnd,
  232: 	    r->tcpInfo.tcpi_rcv_space, r->tcpInfo.tcpi_snd_ssthresh, r->tcpInfo.tcpi_rtt);
  233: #endif
  234: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>