tcp_debug.c revision 126239
11541Srgrimes/* 21541Srgrimes * Copyright (c) 1982, 1986, 1993 31541Srgrimes * The Regents of the University of California. All rights reserved. 41541Srgrimes * 51541Srgrimes * Redistribution and use in source and binary forms, with or without 61541Srgrimes * modification, are permitted provided that the following conditions 71541Srgrimes * are met: 81541Srgrimes * 1. Redistributions of source code must retain the above copyright 91541Srgrimes * notice, this list of conditions and the following disclaimer. 101541Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111541Srgrimes * notice, this list of conditions and the following disclaimer in the 121541Srgrimes * documentation and/or other materials provided with the distribution. 131541Srgrimes * 3. All advertising materials mentioning features or use of this software 141541Srgrimes * must display the following acknowledgement: 151541Srgrimes * This product includes software developed by the University of 161541Srgrimes * California, Berkeley and its contributors. 171541Srgrimes * 4. Neither the name of the University nor the names of its contributors 181541Srgrimes * may be used to endorse or promote products derived from this software 191541Srgrimes * without specific prior written permission. 201541Srgrimes * 211541Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 221541Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 231541Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 241541Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 251541Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 261541Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 271541Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 281541Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 291541Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 301541Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 311541Srgrimes * SUCH DAMAGE. 321541Srgrimes * 331541Srgrimes * @(#)tcp_debug.c 8.1 (Berkeley) 6/10/93 3450477Speter * $FreeBSD: head/sys/netinet/tcp_debug.c 126239 2004-02-25 19:55:29Z mlaier $ 351541Srgrimes */ 361541Srgrimes 3732350Seivind#include "opt_inet.h" 3855679Sshin#include "opt_inet6.h" 3929514Sjoerg#include "opt_tcpdebug.h" 4029514Sjoerg 4132350Seivind#ifndef INET 4232350Seivind#error The option TCPDEBUG requires option INET. 4332350Seivind#endif 4432350Seivind 451541Srgrimes#ifdef TCPDEBUG 461541Srgrimes/* load symbolic names */ 471541Srgrimes#define PRUREQUESTS 481541Srgrimes#define TCPSTATES 491541Srgrimes#define TCPTIMERS 501541Srgrimes#define TANAMES 511541Srgrimes#endif 521541Srgrimes 531541Srgrimes#include <sys/param.h> 541541Srgrimes#include <sys/systm.h> 55126239Smlaier#include <sys/mbuf.h> 561541Srgrimes#include <sys/protosw.h> 5756801Sshin#include <sys/socket.h> 581541Srgrimes 591541Srgrimes#include <netinet/in.h> 601541Srgrimes#include <netinet/in_systm.h> 6155679Sshin#include <netinet/ip.h> 6255679Sshin#ifdef INET6 6362587Sitojun#include <netinet/ip6.h> 6455679Sshin#endif 651541Srgrimes#include <netinet/ip_var.h> 661541Srgrimes#include <netinet/tcp.h> 671541Srgrimes#include <netinet/tcp_fsm.h> 681541Srgrimes#include <netinet/tcp_timer.h> 691541Srgrimes#include <netinet/tcp_var.h> 701541Srgrimes#include <netinet/tcpip.h> 711541Srgrimes#include <netinet/tcp_debug.h> 721541Srgrimes 731541Srgrimes#ifdef TCPDEBUG 7412296Sphkstatic int tcpconsdebug = 0; 751541Srgrimes#endif 7615238Sbde 7715238Sbdestatic struct tcp_debug tcp_debug[TCP_NDEBUG]; 7815238Sbdestatic int tcp_debx; 7915238Sbde 801541Srgrimes/* 811541Srgrimes * Tcp debug routines 821541Srgrimes */ 831541Srgrimesvoid 8455679Sshintcp_trace(act, ostate, tp, ipgen, th, req) 851541Srgrimes short act, ostate; 861541Srgrimes struct tcpcb *tp; 8755679Sshin void *ipgen; 8855679Sshin struct tcphdr *th; 891541Srgrimes int req; 901541Srgrimes{ 9155679Sshin#ifdef INET6 9255679Sshin int isipv6; 9355679Sshin#endif /* INET6 */ 941541Srgrimes tcp_seq seq, ack; 951541Srgrimes int len, flags; 961541Srgrimes struct tcp_debug *td = &tcp_debug[tcp_debx++]; 971541Srgrimes 9855679Sshin#ifdef INET6 9955679Sshin isipv6 = (ipgen != NULL && ((struct ip *)ipgen)->ip_v == 6) ? 1 : 0; 10055679Sshin#endif /* INET6 */ 10156801Sshin td->td_family = 10256801Sshin#ifdef INET6 10356801Sshin (isipv6 != 0) ? AF_INET6 : 10456801Sshin#endif 10556801Sshin AF_INET; 1061541Srgrimes if (tcp_debx == TCP_NDEBUG) 1071541Srgrimes tcp_debx = 0; 1081541Srgrimes td->td_time = iptime(); 1091541Srgrimes td->td_act = act; 1101541Srgrimes td->td_ostate = ostate; 1111541Srgrimes td->td_tcb = (caddr_t)tp; 1121541Srgrimes if (tp) 1131541Srgrimes td->td_cb = *tp; 1141541Srgrimes else 1151541Srgrimes bzero((caddr_t)&td->td_cb, sizeof (*tp)); 11656801Sshin if (ipgen) { 11756801Sshin switch (td->td_family) { 11856801Sshin case AF_INET: 11956801Sshin bcopy((caddr_t)ipgen, (caddr_t)&td->td_ti.ti_i, 12056801Sshin sizeof(td->td_ti.ti_i)); 12156801Sshin bzero((caddr_t)td->td_ip6buf, sizeof(td->td_ip6buf)); 12256801Sshin break; 12355679Sshin#ifdef INET6 12456801Sshin case AF_INET6: 12556801Sshin bcopy((caddr_t)ipgen, (caddr_t)td->td_ip6buf, 12656801Sshin sizeof(td->td_ip6buf)); 12756801Sshin bzero((caddr_t)&td->td_ti.ti_i, 12856801Sshin sizeof(td->td_ti.ti_i)); 12956801Sshin break; 13055679Sshin#endif 13156801Sshin default: 13256801Sshin bzero((caddr_t)td->td_ip6buf, sizeof(td->td_ip6buf)); 13356801Sshin bzero((caddr_t)&td->td_ti.ti_i, 13456801Sshin sizeof(td->td_ti.ti_i)); 13556801Sshin break; 13656801Sshin } 13756801Sshin } else { 13856801Sshin bzero((caddr_t)&td->td_ti.ti_i, sizeof(td->td_ti.ti_i)); 13956801Sshin bzero((caddr_t)td->td_ip6buf, sizeof(td->td_ip6buf)); 14056801Sshin } 14156801Sshin if (th) { 14256801Sshin switch (td->td_family) { 14356801Sshin case AF_INET: 14456801Sshin td->td_ti.ti_t = *th; 14556801Sshin bzero((caddr_t)&td->td_ti6.th, sizeof(td->td_ti6.th)); 14656801Sshin break; 14756801Sshin#ifdef INET6 14856801Sshin case AF_INET6: 14956801Sshin td->td_ti6.th = *th; 15056801Sshin bzero((caddr_t)&td->td_ti.ti_t, 15156801Sshin sizeof(td->td_ti.ti_t)); 15256801Sshin break; 15356801Sshin#endif 15456801Sshin default: 15556801Sshin bzero((caddr_t)&td->td_ti.ti_t, 15656801Sshin sizeof(td->td_ti.ti_t)); 15756801Sshin bzero((caddr_t)&td->td_ti6.th, sizeof(td->td_ti6.th)); 15856801Sshin break; 15956801Sshin } 16056801Sshin } else { 16156801Sshin bzero((caddr_t)&td->td_ti.ti_t, sizeof(td->td_ti.ti_t)); 16256801Sshin bzero((caddr_t)&td->td_ti6.th, sizeof(td->td_ti6.th)); 16356801Sshin } 1641541Srgrimes td->td_req = req; 1651541Srgrimes#ifdef TCPDEBUG 1661541Srgrimes if (tcpconsdebug == 0) 1671541Srgrimes return; 1681541Srgrimes if (tp) 1696283Swollman printf("%p %s:", tp, tcpstates[ostate]); 1701541Srgrimes else 1711541Srgrimes printf("???????? "); 1721541Srgrimes printf("%s ", tanames[act]); 1731541Srgrimes switch (act) { 1741541Srgrimes 1751541Srgrimes case TA_INPUT: 1761541Srgrimes case TA_OUTPUT: 1771541Srgrimes case TA_DROP: 17855679Sshin if (ipgen == NULL || th == NULL) 1791541Srgrimes break; 18055679Sshin seq = th->th_seq; 18155679Sshin ack = th->th_ack; 18255679Sshin len = 18355679Sshin#ifdef INET6 18455679Sshin isipv6 ? ((struct ip6_hdr *)ipgen)->ip6_plen : 18555679Sshin#endif 18655679Sshin ((struct ip *)ipgen)->ip_len; 1871541Srgrimes if (act == TA_OUTPUT) { 1881541Srgrimes seq = ntohl(seq); 1891541Srgrimes ack = ntohl(ack); 1901541Srgrimes len = ntohs((u_short)len); 1911541Srgrimes } 1921541Srgrimes if (act == TA_OUTPUT) 1931541Srgrimes len -= sizeof (struct tcphdr); 1941541Srgrimes if (len) 1951541Srgrimes printf("[%x..%x)", seq, seq+len); 1961541Srgrimes else 1971541Srgrimes printf("%x", seq); 19855679Sshin printf("@%x, urp=%x", ack, th->th_urp); 19955679Sshin flags = th->th_flags; 2001541Srgrimes if (flags) { 2011541Srgrimes char *cp = "<"; 2026283Swollman#define pf(f) { \ 20355679Sshin if (th->th_flags & TH_##f) { \ 2046283Swollman printf("%s%s", cp, #f); \ 2056283Swollman cp = ","; \ 2066283Swollman } \ 2076283Swollman} 2081541Srgrimes pf(SYN); pf(ACK); pf(FIN); pf(RST); pf(PUSH); pf(URG); 2091541Srgrimes printf(">"); 2101541Srgrimes } 2111541Srgrimes break; 2121541Srgrimes 2131541Srgrimes case TA_USER: 2141541Srgrimes printf("%s", prurequests[req&0xff]); 2151541Srgrimes if ((req & 0xff) == PRU_SLOWTIMO) 2161541Srgrimes printf("<%s>", tcptimers[req>>8]); 2171541Srgrimes break; 2181541Srgrimes } 2191541Srgrimes if (tp) 2201541Srgrimes printf(" -> %s", tcpstates[tp->t_state]); 2211541Srgrimes /* print out internal state of tp !?! */ 2221541Srgrimes printf("\n"); 2231541Srgrimes if (tp == 0) 2241541Srgrimes return; 22538373Sbde printf( 22638373Sbde "\trcv_(nxt,wnd,up) (%lx,%lx,%lx) snd_(una,nxt,max) (%lx,%lx,%lx)\n", 22738373Sbde (u_long)tp->rcv_nxt, tp->rcv_wnd, (u_long)tp->rcv_up, 22838373Sbde (u_long)tp->snd_una, (u_long)tp->snd_nxt, (u_long)tp->snd_max); 22938373Sbde printf("\tsnd_(wl1,wl2,wnd) (%lx,%lx,%lx)\n", 23038373Sbde (u_long)tp->snd_wl1, (u_long)tp->snd_wl2, tp->snd_wnd); 2311541Srgrimes#endif /* TCPDEBUG */ 2321541Srgrimes} 233