Annotation of embedaddon/iperf/src/tcp_info.c, revision 1.1.1.1
1.1 misho 1: /*
2: * iperf, Copyright (c) 2014, 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 limitted 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 <netinet/tcp.h>
52: #include <string.h>
53: #include <netinet/in.h>
54: #include <errno.h>
55:
56: #include "iperf.h"
57: #include "iperf_api.h"
58: #include "iperf_locale.h"
59:
60: /*************************************************************/
61: int
62: has_tcpinfo(void)
63: {
64: #if (defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__)) \
65: && defined(TCP_INFO)
66: return 1;
67: #else
68: return 0;
69: #endif
70: }
71:
72: /*************************************************************/
73: int
74: has_tcpinfo_retransmits(void)
75: {
76: #if defined(linux) && defined(TCP_MD5SIG)
77: /* TCP_MD5SIG doesn't actually have anything to do with TCP
78: ** retransmits, it just showed up in the same rev of the header
79: ** file. If it's present then struct tcp_info has the
80: ** tcpi_total_retrans field that we need; if not, not.
81: */
82: return 1;
83: #else
84: #if defined(__FreeBSD__) && __FreeBSD_version >= 600000
85: return 1; /* Should work now */
86: #elif defined(__NetBSD__) && defined(TCP_INFO)
87: return 1;
88: #else
89: return 0;
90: #endif
91: #endif
92: }
93:
94: /*************************************************************/
95: void
96: save_tcpinfo(struct iperf_stream *sp, struct iperf_interval_results *irp)
97: {
98: #if (defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__)) && \
99: defined(TCP_INFO)
100: socklen_t tcp_info_length = sizeof(struct tcp_info);
101:
102: if (getsockopt(sp->socket, IPPROTO_TCP, TCP_INFO, (void *)&irp->tcpInfo, &tcp_info_length) < 0)
103: iperf_err(sp->test, "getsockopt - %s", strerror(errno));
104:
105: if (sp->test->debug) {
106: printf("tcpi_snd_cwnd %u tcpi_snd_mss %u tcpi_rtt %u\n",
107: irp->tcpInfo.tcpi_snd_cwnd, irp->tcpInfo.tcpi_snd_mss,
108: irp->tcpInfo.tcpi_rtt);
109: }
110:
111: #endif
112: }
113:
114: /*************************************************************/
115: long
116: get_total_retransmits(struct iperf_interval_results *irp)
117: {
118: #if defined(linux) && defined(TCP_MD5SIG)
119: return irp->tcpInfo.tcpi_total_retrans;
120: #elif defined(__FreeBSD__) && __FreeBSD_version >= 600000
121: return irp->tcpInfo.tcpi_snd_rexmitpack;
122: #elif defined(__NetBSD__) && defined(TCP_INFO)
123: return irp->tcpInfo.tcpi_snd_rexmitpack;
124: #else
125: return -1;
126: #endif
127: }
128:
129: /*************************************************************/
130: /*
131: * Return snd_cwnd in octets.
132: */
133: long
134: get_snd_cwnd(struct iperf_interval_results *irp)
135: {
136: #if defined(linux) && defined(TCP_MD5SIG)
137: return irp->tcpInfo.tcpi_snd_cwnd * irp->tcpInfo.tcpi_snd_mss;
138: #elif defined(__FreeBSD__) && __FreeBSD_version >= 600000
139: return irp->tcpInfo.tcpi_snd_cwnd * irp->tcpInfo.tcpi_snd_mss;
140: #elif defined(__NetBSD__) && defined(TCP_INFO)
141: return irp->tcpInfo.tcpi_snd_cwnd * irp->tcpInfo.tcpi_snd_mss;
142: #else
143: return -1;
144: #endif
145: }
146:
147: /*************************************************************/
148: /*
149: * Return rtt in usec.
150: */
151: long
152: get_rtt(struct iperf_interval_results *irp)
153: {
154: #if defined(linux) && defined(TCP_MD5SIG)
155: return irp->tcpInfo.tcpi_rtt;
156: #elif defined(__FreeBSD__) && __FreeBSD_version >= 600000
157: return irp->tcpInfo.tcpi_rtt;
158: #elif defined(__NetBSD__) && defined(TCP_INFO)
159: return irp->tcpInfo.tcpi_rtt;
160: #else
161: return -1;
162: #endif
163: }
164:
165: /*************************************************************/
166: void
167: build_tcpinfo_message(struct iperf_interval_results *r, char *message)
168: {
169: #if defined(linux)
170: sprintf(message, report_tcpInfo, r->tcpInfo.tcpi_snd_cwnd, r->tcpInfo.tcpi_snd_ssthresh,
171: r->tcpInfo.tcpi_rcv_ssthresh, r->tcpInfo.tcpi_unacked, r->tcpInfo.tcpi_sacked,
172: r->tcpInfo.tcpi_lost, r->tcpInfo.tcpi_retrans, r->tcpInfo.tcpi_fackets,
173: r->tcpInfo.tcpi_rtt, r->tcpInfo.tcpi_reordering);
174: #endif
175: #if defined(__FreeBSD__)
176: sprintf(message, report_tcpInfo, r->tcpInfo.tcpi_snd_cwnd,
177: r->tcpInfo.tcpi_rcv_space, r->tcpInfo.tcpi_snd_ssthresh, r->tcpInfo.tcpi_rtt);
178: #endif
179: #if defined(__NetBSD__) && defined(TCP_INFO)
180: sprintf(message, report_tcpInfo, r->tcpInfo.tcpi_snd_cwnd,
181: r->tcpInfo.tcpi_rcv_space, r->tcpInfo.tcpi_snd_ssthresh, r->tcpInfo.tcpi_rtt);
182: #endif
183: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>