tcp.c revision 200462
1178253Sdelphij/*- 21573Srgrimes * Copyright (c) 1980, 1992, 1993 31573Srgrimes * The Regents of the University of California. All rights reserved. 41573Srgrimes * 51573Srgrimes * Redistribution and use in source and binary forms, with or without 61573Srgrimes * modification, are permitted provided that the following conditions 71573Srgrimes * are met: 81573Srgrimes * 1. Redistributions of source code must retain the above copyright 91573Srgrimes * notice, this list of conditions and the following disclaimer. 101573Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111573Srgrimes * notice, this list of conditions and the following disclaimer in the 121573Srgrimes * documentation and/or other materials provided with the distribution. 131573Srgrimes * 3. All advertising materials mentioning features or use of this software 141573Srgrimes * must display the following acknowledgement: 151573Srgrimes * This product includes software developed by the University of 161573Srgrimes * California, Berkeley and its contributors. 171573Srgrimes * 4. Neither the name of the University nor the names of its contributors 181573Srgrimes * may be used to endorse or promote products derived from this software 191573Srgrimes * without specific prior written permission. 201573Srgrimes * 211573Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 221573Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 231573Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 241573Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 251573Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 261573Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 271573Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 281573Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 291573Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 301573Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3123668Speter * SUCH DAMAGE. 321573Srgrimes */ 3390039Sobrien 3490039Sobrien#if 0 351573Srgrimes#ifndef lint 3671579Sdeischen/* From: */ 371573Srgrimesstatic char sccsid[] = "@(#)mbufs.c 8.1 (Berkeley) 6/6/93"; 3823768Sbdestatic const char rcsid[] = 397978Sbde "Id: mbufs.c,v 1.5 1997/02/24 20:59:03 wollman Exp"; 401573Srgrimes#endif /* not lint */ 411573Srgrimes#endif 427978Sbde 431573Srgrimes#include <sys/cdefs.h> 441573Srgrimes__FBSDID("$FreeBSD: head/usr.bin/systat/tcp.c 200462 2009-12-13 03:14:06Z delphij $"); 45108631Stjr 461573Srgrimes#include <sys/param.h> 4771579Sdeischen#include <sys/types.h> 481573Srgrimes#include <sys/socket.h> 4969841Sdeischen#include <sys/sysctl.h> 50178256Sdelphij 51178256Sdelphij#include <netinet/in.h> 52178256Sdelphij#include <netinet/in_systm.h> 531573Srgrimes#include <netinet/ip.h> 5423668Speter#include <netinet/tcp.h> 551573Srgrimes#include <netinet/tcp_seq.h> 561573Srgrimes#include <netinet/tcp_fsm.h> 57178253Sdelphij#include <netinet/tcp_timer.h> 581573Srgrimes#include <netinet/tcp_var.h> 5973632Sobrien 6023668Speter#include <stdlib.h> 6123668Speter#include <string.h> 621573Srgrimes#include <paths.h> 63178256Sdelphij 64178256Sdelphij#include "systat.h" 65178256Sdelphij#include "extern.h" 6623668Speter#include "mode.h" 67178256Sdelphij 68178256Sdelphijstatic struct tcpstat curstat, initstat, oldstat; 69249401Sjilles 70178256Sdelphij/*- 71249401Sjilles--0 1 2 3 4 5 6 7 72249401Sjilles--0123456789012345678901234567890123456789012345678901234567890123456789012345 73249401Sjilles00 TCP Connections TCP Packets 74249401Sjilles01999999999999 connections initiated 999999999999 total packets sent 75249401Sjilles02999999999999 connections accepted 999999999999 - data 76249401Sjilles03999999999999 connections established 999999999999 - data (retransmit by dupack) 77249401Sjilles04999999999999 connections dropped 999999999999 - data (retransmit by sack) 78249401Sjilles05999999999999 - in embryonic state 999999999999 - ack-only 79249401Sjilles06999999999999 - on retransmit timeout 999999999999 - window probes 80178256Sdelphij07999999999999 - by keepalive 999999999999 - window updates 81178256Sdelphij08999999999999 - from listen queue 999999999999 - urgent data only 82178256Sdelphij09 999999999999 - control 83178256Sdelphij10 999999999999 - resends by PMTU discovery 84178253Sdelphij11 TCP Timers 999999999999 total packets received 8523668Speter12999999999999 potential rtt updates 999999999999 - in sequence 8623668Speter13999999999999 - successful 999999999999 - completely duplicate 8723668Speter14999999999999 delayed acks sent 999999999999 - with some duplicate data 88249401Sjilles15999999999999 retransmit timeouts 999999999999 - out-of-order 89249401Sjilles16999999999999 persist timeouts 999999999999 - duplicate acks 9023768Sbde17999999999999 keepalive probes 999999999999 - acks 91178256Sdelphij18999999999999 - timeouts 999999999999 - window probes 92178256Sdelphij19 999999999999 - window updates 93178256Sdelphij20 999999999999 - bad checksum 94178256Sdelphij--0123456789012345678901234567890123456789012345678901234567890123456789012345 95201604Skib--0 1 2 3 4 5 6 7 96202679Sache*/ 97201604Skib 98201604SkibWINDOW * 99202572Sacheopentcp(void) 100201604Skib{ 101201604Skib return (subwin(stdscr, LINES-3-1, 0, MAINWIN_ROW, 0)); 102201604Skib} 103201604Skib 104178256Sdelphijvoid 105178256Sdelphijclosetcp(WINDOW *w) 106178256Sdelphij{ 107178256Sdelphij if (w == NULL) 108178256Sdelphij return; 109178256Sdelphij wclear(w); 110178256Sdelphij wrefresh(w); 111178256Sdelphij delwin(w); 112178256Sdelphij} 113178256Sdelphij 114249401Sjillesvoid 115249401Sjilleslabeltcp(void) 11623668Speter{ 117133723Sstefanf wmove(wnd, 0, 0); wclrtoeol(wnd); 11869841Sdeischen#define L(row, str) mvwprintw(wnd, row, 13, str) 11969841Sdeischen#define R(row, str) mvwprintw(wnd, row, 51, str); 12069841Sdeischen L(0, "TCP Connections"); R(0, "TCP Packets"); 1211573Srgrimes L(1, "connections initiated"); R(1, "total packets sent"); 12223768Sbde L(2, "connections accepted"); R(2, "- data"); 12323668Speter L(3, "connections established"); R(3, "- data (retransmit by dupack)"); 12471579Sdeischen L(4, "connections dropped"); R(4, "- data (retransmit by sack)"); 1251573Srgrimes L(5, "- in embryonic state"); R(5, "- ack-only"); 12623668Speter L(6, "- on retransmit timeout"); R(6, "- window probes"); 12723668Speter L(7, "- by keepalive"); R(7, "- window updates"); 12823668Speter L(8, "- from listen queue"); R(8, "- urgent data only"); 12923668Speter R(9, "- control"); 13023668Speter R(10, "- resends by PMTU discovery"); 13123668Speter L(11, "TCP Timers"); R(11, "total packets received"); 13223668Speter L(12, "potential rtt updates"); R(12, "- in sequence"); 13323668Speter L(13, "- successful"); R(13, "- completely duplicate"); 13423668Speter L(14, "delayed acks sent"); R(14, "- with some duplicate data"); 13523668Speter L(15, "retransmit timeouts"); R(15, "- out-of-order"); 13671579Sdeischen L(16, "persist timeouts"); R(16, "- duplicate acks"); 13723768Sbde L(17, "keepalive probes"); R(17, "- acks"); 138115047Stjr L(18, "- timeouts"); R(18, "- window probes"); 13975860Sjoerg R(19, "- window updates"); 14023668Speter R(20, "- bad checksum"); 14123668Speter#undef L 14223668Speter#undef R 14323668Speter} 14423668Speter 14523668Speterstatic void 14623668Speterdomode(struct tcpstat *ret) 14723668Speter{ 14823668Speter const struct tcpstat *sub; 14923668Speter int divisor = 1; 15023668Speter 15123668Speter switch(currentmode) { 15223668Speter case display_RATE: 15323668Speter sub = &oldstat; 15423668Speter divisor = naptime; 15523668Speter break; 15623668Speter case display_DELTA: 15723668Speter sub = &oldstat; 15823668Speter break; 15923668Speter case display_SINCE: 16023668Speter sub = &initstat; 16123668Speter break; 16223668Speter default: 16371579Sdeischen *ret = curstat; 16423668Speter return; 16523668Speter } 16623668Speter#define DO(stat) ret->stat = (curstat.stat - sub->stat) / divisor 16723668Speter DO(tcps_connattempt); 16839327Simp DO(tcps_accepts); 16923768Sbde DO(tcps_connects); 17023768Sbde DO(tcps_drops); 17123668Speter DO(tcps_conndrops); 17223668Speter DO(tcps_closed); 17323668Speter DO(tcps_segstimed); 17471579Sdeischen DO(tcps_rttupdated); 17523668Speter DO(tcps_delack); 17623668Speter DO(tcps_timeoutdrop); 17723668Speter DO(tcps_rexmttimeo); 17823668Speter DO(tcps_persisttimeo); 17923668Speter DO(tcps_keeptimeo); 18023668Speter DO(tcps_keepprobe); 18123668Speter DO(tcps_keepdrops); 18223668Speter 18323668Speter DO(tcps_sndtotal); 18423668Speter DO(tcps_sndpack); 18523668Speter DO(tcps_sndbyte); 18623668Speter DO(tcps_sndrexmitpack); 18723668Speter DO(tcps_sack_rexmits); 18823668Speter DO(tcps_sndacks); 18923668Speter DO(tcps_sndprobe); 19023668Speter DO(tcps_sndurg); 19123668Speter DO(tcps_sndwinup); 19256698Sjasone DO(tcps_sndctrl); 193261813Sjilles 194261813Sjilles DO(tcps_rcvtotal); 19523768Sbde DO(tcps_rcvpack); 19623668Speter DO(tcps_rcvbyte); 19723668Speter DO(tcps_rcvbadsum); 19823768Sbde DO(tcps_rcvbadoff); 19923668Speter DO(tcps_rcvshort); 20023668Speter DO(tcps_rcvduppack); 20123668Speter DO(tcps_rcvdupbyte); 20223668Speter DO(tcps_rcvpartduppack); 20323668Speter DO(tcps_rcvpartdupbyte); 20423668Speter DO(tcps_rcvoopack); 20523668Speter DO(tcps_rcvoobyte); 20623668Speter DO(tcps_rcvpackafterwin); 20723668Speter DO(tcps_rcvbyteafterwin); 20823668Speter DO(tcps_rcvafterclose); 20923668Speter DO(tcps_rcvwinprobe); 21023668Speter DO(tcps_rcvdupack); 21123668Speter DO(tcps_rcvacktoomuch); 21223668Speter DO(tcps_rcvackpack); 21323668Speter DO(tcps_rcvackbyte); 21423668Speter DO(tcps_rcvwinupd); 21523668Speter DO(tcps_pawsdrop); 21623668Speter DO(tcps_predack); 21723668Speter DO(tcps_preddat); 21823668Speter DO(tcps_pcbcachemiss); 21923668Speter DO(tcps_cachedrtt); 22023668Speter DO(tcps_cachedrttvar); 22123668Speter DO(tcps_cachedssthresh); 22223668Speter DO(tcps_usedrtt); 22334357Sjb DO(tcps_usedrttvar); 22423668Speter DO(tcps_usedssthresh); 22523668Speter DO(tcps_persistdrop); 22623668Speter DO(tcps_badsyn); 22723668Speter DO(tcps_mturesent); 22823668Speter DO(tcps_listendrop); 22923668Speter#undef DO 23023668Speter} 23123668Speter 23223668Spetervoid 23323668Spetershowtcp(void) 23423668Speter{ 23523668Speter struct tcpstat stats; 23623668Speter 23723668Speter memset(&stats, 0, sizeof stats); 23823668Speter domode(&stats); 23923668Speter 24023668Speter#define DO(stat, row, col) \ 24123668Speter mvwprintw(wnd, row, col, "%12lu", stats.stat) 242201604Skib#define L(row, stat) DO(stat, row, 0) 243202679Sache#define R(row, stat) DO(stat, row, 38) 24423668Speter L(1, tcps_connattempt); R(1, tcps_sndtotal); 24523668Speter L(2, tcps_accepts); R(2, tcps_sndpack); 24623668Speter L(3, tcps_connects); R(3, tcps_sndrexmitpack); 24723668Speter L(4, tcps_drops); R(4, tcps_sack_rexmits); 24823668Speter L(5, tcps_conndrops); R(5, tcps_sndacks); 24923668Speter L(6, tcps_timeoutdrop); R(6, tcps_sndprobe); 25023668Speter L(7, tcps_keepdrops); R(7, tcps_sndwinup); 25123668Speter L(8, tcps_listendrop); R(8, tcps_sndurg); 25223668Speter R(9, tcps_sndctrl); 25323668Speter R(10, tcps_mturesent); 25423668Speter R(11, tcps_rcvtotal); 25523668Speter L(12, tcps_segstimed); R(12, tcps_rcvpack); 25623668Speter L(13, tcps_rttupdated); R(13, tcps_rcvduppack); 25723668Speter L(14, tcps_delack); R(14, tcps_rcvpartduppack); 25823668Speter L(15, tcps_rexmttimeo); R(15, tcps_rcvoopack); 25923668Speter L(16, tcps_persisttimeo); R(16, tcps_rcvdupack); 26023668Speter L(17, tcps_keepprobe); R(17, tcps_rcvackpack); 26123668Speter L(18, tcps_keeptimeo); R(18, tcps_rcvwinprobe); 26223668Speter R(19, tcps_rcvwinupd); 26323668Speter R(20, tcps_rcvbadsum); 26423668Speter#undef DO 26523668Speter#undef L 26623668Speter#undef R 26723668Speter} 26823668Speter 26923668Speterint 27023668Speterinittcp(void) 27123668Speter{ 27223668Speter size_t len; 27323668Speter int name[4]; 27423668Speter 27523668Speter name[0] = CTL_NET; 27623668Speter name[1] = PF_INET; 27723668Speter name[2] = IPPROTO_TCP; 27823668Speter name[3] = TCPCTL_STATS; 27923668Speter 280123861Sdfr len = 0; 28123668Speter if (sysctl(name, 4, 0, &len, 0, 0) < 0) { 28223768Sbde error("sysctl getting tcpstat size failed"); 28323768Sbde return 0; 28423668Speter } 28523668Speter if (len > sizeof curstat) { 28623668Speter error("tcpstat structure has grown--recompile systat!"); 28723668Speter return 0; 28823668Speter } 2891573Srgrimes if (sysctl(name, 4, &initstat, &len, 0, 0) < 0) { 29023668Speter error("sysctl getting tcpstat failed"); 29171579Sdeischen return 0; 29223668Speter } 2931573Srgrimes oldstat = initstat; 2941573Srgrimes return 1; 2951573Srgrimes} 2961573Srgrimes 2977978Sbdevoid 29823668Speterresettcp(void) 29923768Sbde{ 30023768Sbde size_t len; 30123768Sbde int name[4]; 30223768Sbde 30356698Sjasone name[0] = CTL_NET; 30423768Sbde name[1] = PF_INET; 30523768Sbde name[2] = IPPROTO_TCP; 3061573Srgrimes name[3] = TCPCTL_STATS; 307 308 len = sizeof initstat; 309 if (sysctl(name, 4, &initstat, &len, 0, 0) < 0) { 310 error("sysctl getting tcpstat failed"); 311 } 312 oldstat = initstat; 313} 314 315void 316fetchtcp(void) 317{ 318 int name[4]; 319 size_t len; 320 321 oldstat = curstat; 322 name[0] = CTL_NET; 323 name[1] = PF_INET; 324 name[2] = IPPROTO_TCP; 325 name[3] = TCPCTL_STATS; 326 len = sizeof curstat; 327 328 if (sysctl(name, 4, &curstat, &len, 0, 0) < 0) 329 return; 330} 331 332