xref: /xnu-8796.101.5/bsd/netinet/tcp_debug.c (revision aca3beaa3dfbd42498b42c5e5ce20a938e6554e5)
1 /*
2  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3  *
4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5  *
6  * This file contains Original Code and/or Modifications of Original Code
7  * as defined in and that are subject to the Apple Public Source License
8  * Version 2.0 (the 'License'). You may not use this file except in
9  * compliance with the License. The rights granted to you under the License
10  * may not be used to create, or enable the creation or redistribution of,
11  * unlawful or unlicensed copies of an Apple operating system, or to
12  * circumvent, violate, or enable the circumvention or violation of, any
13  * terms of an Apple operating system software license agreement.
14  *
15  * Please obtain a copy of the License at
16  * http://www.opensource.apple.com/apsl/ and read it before using this file.
17  *
18  * The Original Code and all software distributed under the License are
19  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23  * Please see the License for the specific language governing rights and
24  * limitations under the License.
25  *
26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27  */
28 /*
29  * Copyright (c) 1982, 1986, 1993
30  *	The Regents of the University of California.  All rights reserved.
31  *
32  * Redistribution and use in source and binary forms, with or without
33  * modification, are permitted provided that the following conditions
34  * are met:
35  * 1. Redistributions of source code must retain the above copyright
36  *    notice, this list of conditions and the following disclaimer.
37  * 2. Redistributions in binary form must reproduce the above copyright
38  *    notice, this list of conditions and the following disclaimer in the
39  *    documentation and/or other materials provided with the distribution.
40  * 3. All advertising materials mentioning features or use of this software
41  *    must display the following acknowledgement:
42  *	This product includes software developed by the University of
43  *	California, Berkeley and its contributors.
44  * 4. Neither the name of the University nor the names of its contributors
45  *    may be used to endorse or promote products derived from this software
46  *    without specific prior written permission.
47  *
48  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
49  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
52  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58  * SUCH DAMAGE.
59  *
60  *	@(#)tcp_debug.c	8.1 (Berkeley) 6/10/93
61  * $FreeBSD: src/sys/netinet/tcp_debug.c,v 1.16.2.1 2000/07/15 07:14:31 kris Exp $
62  */
63 
64 
65 #ifndef INET
66 #error The option TCPDEBUG requires option INET.
67 #endif
68 
69 #if TCPDEBUG
70 /* load symbolic names */
71 #define PRUREQUESTS
72 #define TCPSTATES
73 #define TCPTIMERS
74 #define TANAMES
75 #endif
76 
77 #include <sys/param.h>
78 #include <sys/systm.h>
79 #include <sys/protosw.h>
80 #include <sys/sysctl.h>
81 #include <sys/socket.h>
82 
83 #include <netinet/in.h>
84 #include <netinet/in_systm.h>
85 #include <netinet/ip.h>
86 #include <netinet/ip6.h>
87 #include <netinet/ip_var.h>
88 #include <netinet/tcp.h>
89 #include <netinet/tcp_fsm.h>
90 #include <netinet/tcp_timer.h>
91 #include <netinet/tcp_var.h>
92 #include <netinet/tcpip.h>
93 #include <netinet/tcp_debug.h>
94 
95 #if TCPDEBUG
96 __private_extern__ int  tcpconsdebug = 0;
97 SYSCTL_INT(_net_inet_tcp, OID_AUTO, tcpconsdebug, CTLFLAG_RW | CTLFLAG_LOCKED,
98     &tcpconsdebug, 0, "Turn tcp debugging on or off");
99 #endif
100 
101 static struct tcp_debug tcp_debug[TCP_NDEBUG];
102 static int      tcp_debx;
103 
104 /*
105  * Tcp debug routines
106  */
107 void
tcp_trace(act,ostate,tp,ipgen,th,req)108 tcp_trace(act, ostate, tp, ipgen, th, req)
109 short act, ostate;
110 struct tcpcb *tp;
111 void *ipgen;
112 struct tcphdr *th;
113 int req;
114 {
115 	int isipv6;
116 	tcp_seq seq, ack;
117 	int len, flags;
118 	struct tcp_debug *td = &tcp_debug[tcp_debx++];
119 
120 	isipv6 = (ipgen != NULL && ((struct ip *)ipgen)->ip_v == 6) ? 1 : 0;
121 	td->td_family = (isipv6 != 0) ? AF_INET6 : AF_INET;
122 	if (tcp_debx == TCP_NDEBUG) {
123 		tcp_debx = 0;
124 	}
125 	td->td_time = iptime();
126 	td->td_act = act;
127 	td->td_ostate = ostate;
128 	td->td_tcb = (caddr_t)tp;
129 	if (tp) {
130 		td->td_cb = *tp;
131 	} else {
132 		bzero((caddr_t)&td->td_cb, sizeof(*tp));
133 	}
134 	if (ipgen) {
135 		switch (td->td_family) {
136 		case AF_INET:
137 			bcopy((caddr_t)ipgen, (caddr_t)&td->td_ti.ti_i,
138 			    sizeof(td->td_ti.ti_i));
139 			bzero((caddr_t)td->td_ip6buf, sizeof(td->td_ip6buf));
140 			break;
141 		case AF_INET6:
142 			bcopy((caddr_t)ipgen, (caddr_t)td->td_ip6buf,
143 			    sizeof(td->td_ip6buf));
144 			bzero((caddr_t)&td->td_ti.ti_i,
145 			    sizeof(td->td_ti.ti_i));
146 			break;
147 		default:
148 			bzero((caddr_t)td->td_ip6buf, sizeof(td->td_ip6buf));
149 			bzero((caddr_t)&td->td_ti.ti_i,
150 			    sizeof(td->td_ti.ti_i));
151 			break;
152 		}
153 	} else {
154 		bzero((caddr_t)&td->td_ti.ti_i, sizeof(td->td_ti.ti_i));
155 		bzero((caddr_t)td->td_ip6buf, sizeof(td->td_ip6buf));
156 	}
157 	if (th) {
158 		switch (td->td_family) {
159 		case AF_INET:
160 			td->td_ti.ti_t = *th;
161 			bzero((caddr_t)&td->td_ti6.th, sizeof(td->td_ti6.th));
162 			break;
163 		case AF_INET6:
164 			td->td_ti6.th = *th;
165 			bzero((caddr_t)&td->td_ti.ti_t,
166 			    sizeof(td->td_ti.ti_t));
167 			break;
168 		default:
169 			bzero((caddr_t)&td->td_ti.ti_t,
170 			    sizeof(td->td_ti.ti_t));
171 			bzero((caddr_t)&td->td_ti6.th, sizeof(td->td_ti6.th));
172 			break;
173 		}
174 	} else {
175 		bzero((caddr_t)&td->td_ti.ti_t, sizeof(td->td_ti.ti_t));
176 		bzero((caddr_t)&td->td_ti6.th, sizeof(td->td_ti6.th));
177 	}
178 	td->td_req = req;
179 #if TCPDEBUG
180 	if (tcpconsdebug == 0) {
181 		return;
182 	}
183 	if (tp) {
184 		printf("%x %s:", tp, tcpstates[ostate]);
185 	} else {
186 		printf("???????? ");
187 	}
188 	printf("%s ", tanames[act]);
189 	switch (act) {
190 	case TA_INPUT:
191 	case TA_OUTPUT:
192 	case TA_DROP:
193 		if (ipgen == NULL || th == NULL) {
194 			break;
195 		}
196 		seq = th->th_seq;
197 		ack = th->th_ack;
198 		len = isipv6 ? ((struct ip6_hdr *)ipgen)->ip6_plen : ((struct ip *)ipgen)->ip_len;
199 		if (act == TA_OUTPUT) {
200 			seq = ntohl(seq);
201 			ack = ntohl(ack);
202 			len = ntohs((u_short)len);
203 		}
204 		if (act == TA_OUTPUT) {
205 			len -= sizeof(struct tcphdr);
206 		}
207 		if (len) {
208 			printf("[%x..%x)", seq, seq + len);
209 		} else {
210 			printf("%x", seq);
211 		}
212 		printf("@%x, urp=%x", ack, th->th_urp);
213 		flags = th->th_flags;
214 		if (flags) {
215 			char *cp = "<";
216 #define pf(f) {                                 \
217 	if (th->th_flags & TH_##f) {            \
218 	        printf("%s%s", cp, #f);         \
219 	        cp = ",";                       \
220 	}                                       \
221 }
222 			pf(SYN); pf(ACK); pf(FIN); pf(RST); pf(PUSH); pf(URG);
223 			printf(">");
224 		}
225 		break;
226 
227 	case TA_USER:
228 		printf("%s", prurequests[req & 0xff]);
229 		if ((req & 0xff) == PRU_SLOWTIMO) {
230 			printf("<%s>", tcptimers[req >> 8]);
231 		}
232 		break;
233 	}
234 	if (tp) {
235 		printf(" -> %s", tcpstates[tp->t_state]);
236 	}
237 	/* print out internal state of tp !?! */
238 	printf("\n");
239 	if (tp == 0) {
240 		return;
241 	}
242 	printf(
243 		"\trcv_(nxt,wnd,up) (%lx,%lx,%lx) snd_(una,nxt,max) (%lx,%lx,%lx)\n",
244 		(uint32_t)tp->rcv_nxt, tp->rcv_wnd, (uint32_t)tp->rcv_up,
245 		(uint32_t)tp->snd_una, (uint32_t)tp->snd_nxt, (uint32_t)tp->snd_max);
246 	printf("\tsnd_(wl1,wl2,wnd) (%lx,%lx,%lx)\n",
247 	    (uint32_t)tp->snd_wl1, (uint32_t)tp->snd_wl2, tp->snd_wnd);
248 #endif /* TCPDEBUG */
249 }
250