File:  [DragonFly] / src / usr.bin / systat / tcp.c
Revision 1.5: download - view: text, annotated - select for diffs
Wed Apr 7 21:40:19 2004 UTC (10 years ago) by dillon
Branches: MAIN
CVS tags: HEAD, DragonFly_Stable, DragonFly_Snap29Sep2004, DragonFly_Snap13Sep2004, DragonFly_RELEASE_2_0_Slip, DragonFly_RELEASE_2_0, DragonFly_RELEASE_1_8_Slip, DragonFly_RELEASE_1_8, DragonFly_RELEASE_1_6_Slip, DragonFly_RELEASE_1_6, DragonFly_RELEASE_1_4_Slip, DragonFly_RELEASE_1_4, DragonFly_RELEASE_1_2_Slip, DragonFly_RELEASE_1_2, DragonFly_RELEASE_1_12_Slip, DragonFly_RELEASE_1_12, DragonFly_RELEASE_1_10_Slip, DragonFly_RELEASE_1_10, DragonFly_Preview, DragonFly_1_0_REL, DragonFly_1_0_RC1, DragonFly_1_0A_REL
TCP statistics structure renamed tcpstat -> tcp_stats.

    1: /*-
    2:  * Copyright (c) 1980, 1992, 1993
    3:  *	The Regents of the University of California.  All rights reserved.
    4:  *
    5:  * Redistribution and use in source and binary forms, with or without
    6:  * modification, are permitted provided that the following conditions
    7:  * are met:
    8:  * 1. Redistributions of source code must retain the above copyright
    9:  *    notice, this list of conditions and the following disclaimer.
   10:  * 2. Redistributions in binary form must reproduce the above copyright
   11:  *    notice, this list of conditions and the following disclaimer in the
   12:  *    documentation and/or other materials provided with the distribution.
   13:  * 3. All advertising materials mentioning features or use of this software
   14:  *    must display the following acknowledgement:
   15:  *	This product includes software developed by the University of
   16:  *	California, Berkeley and its contributors.
   17:  * 4. Neither the name of the University nor the names of its contributors
   18:  *    may be used to endorse or promote products derived from this software
   19:  *    without specific prior written permission.
   20:  *
   21:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   22:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   23:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   24:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   25:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   26:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   27:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   28:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   29:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   30:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   31:  * SUCH DAMAGE.
   32:  *
   33:  * @(#)mbufs.c	8.1 (Berkeley) 6/6/93
   34:  * $FreeBSD: src/usr.bin/systat/tcp.c,v 1.3 1999/08/28 01:06:06 peter Exp $
   35:  * $DragonFly: src/usr.bin/systat/tcp.c,v 1.5 2004/04/07 21:40:19 dillon Exp $
   36:  */
   37: 
   38: #include <sys/param.h>
   39: #include <sys/types.h>
   40: #include <sys/socket.h>
   41: #include <sys/sysctl.h>
   42: 
   43: #include <netinet/in.h>
   44: #include <netinet/in_systm.h>
   45: #include <netinet/ip.h>
   46: #include <netinet/tcp.h>
   47: #include <netinet/tcp_seq.h>
   48: #include <netinet/tcp_fsm.h>
   49: #include <netinet/tcp_timer.h>
   50: #include <netinet/tcp_var.h>
   51: 
   52: #include <stdlib.h>
   53: #include <string.h>
   54: #include <paths.h>
   55: #include "systat.h"
   56: #include "extern.h"
   57: #include "mode.h"
   58: 
   59: static struct tcp_stats curstat, initstat, oldstat;
   60: 
   61: /*-
   62: --0         1         2         3         4         5         6         7
   63: --0123456789012345678901234567890123456789012345678901234567890123456789012345
   64: 01          TCP Connections                    TCP Packets
   65: 02999999999 connections initiated    999999999 total packets sent
   66: 03999999999 connections accepted     999999999 - data
   67: 04999999999 connections established  999999999 - data (retransmit)
   68: 05999999999 connections dropped      999999999 - ack-only
   69: 06999999999 - in embryonic state     999999999 - window probes
   70: 07999999999 - on retransmit timeout  999999999 - window updates
   71: 08999999999 - by keepalive           999999999 - urgent data only
   72: 09999999999 - from listen queue      999999999 - control
   73: 10                                   999999999 - resends by PMTU discovery
   74: 11          TCP Timers               999999999 total packets received
   75: 12999999999 potential rtt updates    999999999 - in sequence
   76: 13999999999 - successful             999999999 - completely duplicate
   77: 14999999999 delayed acks sent        999999999 - with some duplicate data
   78: 15999999999 retransmit timeouts      999999999 - out-of-order
   79: 16999999999 persist timeouts         999999999 - duplicate acks
   80: 17999999999 keepalive probes         999999999 - acks
   81: 18999999999 - timeouts               999999999 - window probes
   82: 19                                   999999999 - window updates
   83: --0123456789012345678901234567890123456789012345678901234567890123456789012345
   84: --0         1         2         3         4         5         6         7
   85: */
   86: 
   87: WINDOW *
   88: opentcp(void)
   89: {
   90: 	return (subwin(stdscr, LINES-5-1, 0, 5, 0));
   91: }
   92: 
   93: void
   94: closetcp(WINDOW *w)
   95: {
   96: 	if (w == NULL)
   97: 		return;
   98: 	wclear(w);
   99: 	wrefresh(w);
  100: 	delwin(w);
  101: }
  102: 
  103: void
  104: labeltcp(void)
  105: {
  106: 	wmove(wnd, 0, 0); wclrtoeol(wnd);
  107: #define L(row, str) mvwprintw(wnd, row, 10, str)
  108: #define R(row, str) mvwprintw(wnd, row, 45, str);
  109: 	L(1, "TCP Connections");		R(1, "TCP Packets");
  110: 	L(2, "connections initiated");		R(2, "total packets sent");
  111: 	L(3, "connections accepted");		R(3, "- data");
  112: 	L(4, "connections established");	R(4, "- data (retransmit)");
  113: 	L(5, "connections dropped");		R(5, "- ack-only");
  114: 	L(6, "- in embryonic state");		R(6, "- window probes");
  115: 	L(7, "- on retransmit timeout");	R(7, "- window updates");
  116: 	L(8, "- by keepalive");			R(8, "- urgent data only");
  117: 	L(9, "- from listen queue");		R(9, "- control");
  118: 	R(10, "- resends by PMTU discovery");
  119: 	L(11, "TCP Timers");		R(11, "total packets received");
  120: 	L(12, "potential rtt updates");		R(12, "- in sequence");
  121: 	L(13, "- successful");		R(13, "- completely duplicate");
  122: 	L(14, "delayed acks sent");	R(14, "- with some duplicate data");
  123: 	L(15, "retransmit timeouts");	R(15, "- out-of-order");
  124: 	L(16, "persist timeouts");	R(16, "- duplicate acks");
  125: 	L(17, "keepalive probes");	R(17, "- acks");
  126: 	L(18, "- timeouts");		R(18, "- window probes");
  127: 	R(19, "- window updates");
  128: #undef L
  129: #undef R
  130: }
  131: 
  132: static void
  133: domode(struct tcp_stats *ret)
  134: {
  135: 	const struct tcp_stats *sub;
  136: 	double divisor = 1.0;
  137: 
  138: 	switch(currentmode) {
  139: 	case display_RATE:
  140: 		sub = &oldstat;
  141: 		divisor = naptime;
  142: 		break;
  143: 	case display_DELTA:
  144: 		sub = &oldstat;
  145: 		break;
  146: 	case display_SINCE:
  147: 		sub = &initstat;
  148: 		break;
  149: 	default:
  150: 		*ret = curstat;
  151: 		return;
  152: 	}
  153: #define DO(stat) ret->stat = (double)(curstat.stat - sub->stat) / divisor
  154: 	DO(tcps_connattempt);
  155: 	DO(tcps_accepts);
  156: 	DO(tcps_connects);
  157: 	DO(tcps_drops);
  158: 	DO(tcps_conndrops);
  159: 	DO(tcps_closed);
  160: 	DO(tcps_segstimed);
  161: 	DO(tcps_rttupdated);
  162: 	DO(tcps_delack);
  163: 	DO(tcps_timeoutdrop);
  164: 	DO(tcps_rexmttimeo);
  165: 	DO(tcps_persisttimeo);
  166: 	DO(tcps_keeptimeo);
  167: 	DO(tcps_keepprobe);
  168: 	DO(tcps_keepdrops);
  169: 
  170: 	DO(tcps_sndtotal);
  171: 	DO(tcps_sndpack);
  172: 	DO(tcps_sndbyte);
  173: 	DO(tcps_sndrexmitpack);
  174: 	DO(tcps_sndrexmitbyte);
  175: 	DO(tcps_sndacks);
  176: 	DO(tcps_sndprobe);
  177: 	DO(tcps_sndurg);
  178: 	DO(tcps_sndwinup);
  179: 	DO(tcps_sndctrl);
  180: 
  181: 	DO(tcps_rcvtotal);
  182: 	DO(tcps_rcvpack);
  183: 	DO(tcps_rcvbyte);
  184: 	DO(tcps_rcvbadsum);
  185: 	DO(tcps_rcvbadoff);
  186: 	DO(tcps_rcvshort);
  187: 	DO(tcps_rcvduppack);
  188: 	DO(tcps_rcvdupbyte);
  189: 	DO(tcps_rcvpartduppack);
  190: 	DO(tcps_rcvpartdupbyte);
  191: 	DO(tcps_rcvoopack);
  192: 	DO(tcps_rcvoobyte);
  193: 	DO(tcps_rcvpackafterwin);
  194: 	DO(tcps_rcvbyteafterwin);
  195: 	DO(tcps_rcvafterclose);
  196: 	DO(tcps_rcvwinprobe);
  197: 	DO(tcps_rcvdupack);
  198: 	DO(tcps_rcvacktoomuch);
  199: 	DO(tcps_rcvackpack);
  200: 	DO(tcps_rcvackbyte);
  201: 	DO(tcps_rcvwinupd);
  202: 	DO(tcps_pawsdrop);
  203: 	DO(tcps_predack);
  204: 	DO(tcps_preddat);
  205: 	DO(tcps_pcbcachemiss);
  206: 	DO(tcps_cachedrtt);
  207: 	DO(tcps_cachedrttvar);
  208: 	DO(tcps_cachedssthresh);
  209: 	DO(tcps_usedrtt);
  210: 	DO(tcps_usedrttvar);
  211: 	DO(tcps_usedssthresh);
  212: 	DO(tcps_persistdrop);
  213: 	DO(tcps_badsyn);
  214: 	DO(tcps_mturesent);
  215: 	DO(tcps_listendrop);
  216: #undef DO
  217: }
  218: 	
  219: void
  220: showtcp(void)
  221: {
  222: 	struct tcp_stats stats;
  223: 
  224: 	memset(&stats, 0, sizeof stats);
  225: 	domode(&stats);
  226: 
  227: #define DO(stat, row, col) \
  228: 	mvwprintw(wnd, row, col, "%9lu", stats.stat)
  229: #define	L(row, stat) DO(stat, row, 0)
  230: #define	R(row, stat) DO(stat, row, 35)
  231: 	L(2, tcps_connattempt);		R(2, tcps_sndtotal);
  232: 	L(3, tcps_accepts);		R(3, tcps_sndpack);
  233: 	L(4, tcps_connects);		R(4, tcps_sndrexmitpack);
  234: 	L(5, tcps_drops);		R(5, tcps_sndacks);
  235: 	L(6, tcps_conndrops);		R(6, tcps_sndprobe);
  236: 	L(7, tcps_timeoutdrop);		R(7, tcps_sndwinup);
  237: 	L(8, tcps_keepdrops);		R(8, tcps_sndurg);
  238: 	L(9, tcps_listendrop);		R(9, tcps_sndctrl);
  239: 	R(10, tcps_mturesent);
  240: 	R(11, tcps_rcvtotal);
  241: 	L(12, tcps_segstimed);		R(12, tcps_rcvpack);
  242: 	L(13, tcps_rttupdated);		R(13, tcps_rcvduppack);
  243: 	L(14, tcps_delack);		R(14, tcps_rcvpartduppack);
  244: 	L(15, tcps_rexmttimeo);		R(15, tcps_rcvoopack);
  245: 	L(16, tcps_persisttimeo);	R(16, tcps_rcvdupack);
  246: 	L(17, tcps_keepprobe);		R(17, tcps_rcvackpack);
  247: 	L(18, tcps_keeptimeo);		R(18, tcps_rcvwinprobe);
  248: 	R(19, tcps_rcvwinupd);
  249: #undef DO
  250: #undef L
  251: #undef R
  252: }
  253: 
  254: int
  255: inittcp(void)
  256: {
  257: 	size_t len;
  258: 	int name[4];
  259: 
  260: 	name[0] = CTL_NET;
  261: 	name[1] = PF_INET;
  262: 	name[2] = IPPROTO_TCP;
  263: 	name[3] = TCPCTL_STATS;
  264: 
  265: 	len = 0;
  266: 	if (sysctl(name, 4, 0, &len, 0, 0) < 0) {
  267: 		error("sysctl getting tcp_stats size failed");
  268: 		return 0;
  269: 	}
  270: 	if (len > sizeof curstat) {
  271: 		error("tcp_stats structure has grown--recompile systat!");
  272: 		return 0;
  273: 	}
  274: 	if (sysctl(name, 4, &initstat, &len, 0, 0) < 0) {
  275: 		error("sysctl getting tcp_stats failed");
  276: 		return 0;
  277: 	}
  278: 	oldstat = initstat;
  279: 	return 1;
  280: }
  281: 
  282: void
  283: resettcp(void)
  284: {
  285: 	size_t len;
  286: 	int name[4];
  287: 
  288: 	name[0] = CTL_NET;
  289: 	name[1] = PF_INET;
  290: 	name[2] = IPPROTO_TCP;
  291: 	name[3] = TCPCTL_STATS;
  292: 
  293: 	len = sizeof initstat;
  294: 	if (sysctl(name, 4, &initstat, &len, 0, 0) < 0) {
  295: 		error("sysctl getting tcp_stats failed");
  296: 	}
  297: 	oldstat = initstat;
  298: }
  299: 
  300: void
  301: fetchtcp(void)
  302: {
  303: 	int name[4];
  304: 	size_t len;
  305: 
  306: 	oldstat = curstat;
  307: 	name[0] = CTL_NET;
  308: 	name[1] = PF_INET;
  309: 	name[2] = IPPROTO_TCP;
  310: 	name[3] = TCPCTL_STATS;
  311: 	len = sizeof curstat;
  312: 
  313: 	if (sysctl(name, 4, &curstat, &len, 0, 0) < 0)
  314: 		return;
  315: }
  316: