]> git.saurik.com Git - apple/network_cmds.git/blob - trsp.tproj/trsp.c
network_cmds-85.tar.gz
[apple/network_cmds.git] / trsp.tproj / trsp.c
1 /*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.0 (the 'License'). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
12 * this file.
13 *
14 * The Original Code and all software distributed under the License are
15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
20 * under the License."
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24 /*
25 * Copyright (c) 1985, 1993
26 * The Regents of the University of California. All rights reserved.
27 *
28 * Redistribution and use in source and binary forms, with or without
29 * modification, are permitted provided that the following conditions
30 * are met:
31 * 1. Redistributions of source code must retain the above copyright
32 * notice, this list of conditions and the following disclaimer.
33 * 2. Redistributions in binary form must reproduce the above copyright
34 * notice, this list of conditions and the following disclaimer in the
35 * documentation and/or other materials provided with the distribution.
36 * 3. All advertising materials mentioning features or use of this software
37 * must display the following acknowledgement:
38 * This product includes software developed by the University of
39 * California, Berkeley and its contributors.
40 * 4. Neither the name of the University nor the names of its contributors
41 * may be used to endorse or promote products derived from this software
42 * without specific prior written permission.
43 *
44 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
45 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
46 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
47 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
48 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
49 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
50 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
51 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
52 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
53 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
54 * SUCH DAMAGE.
55 */
56
57 #ifndef lint
58 static char copyright[] =
59 "@(#) Copyright (c) 1985, 1993\n\
60 The Regents of the University of California. All rights reserved.\n";
61 #endif /* not lint */
62
63 #ifndef lint
64 static char sccsid[] = "@(#)trsp.c 8.1 (Berkeley) 6/6/93";
65 #endif /* not lint */
66
67 #include <unistd.h>
68 #include <stdlib.h>
69 #include <sys/cdefs.h>
70 #include <sys/param.h>
71 #include <sys/socket.h>
72 #include <sys/socketvar.h>
73 #define PRUREQUESTS
74 #include <sys/protosw.h>
75
76 #include <net/route.h>
77 #include <net/if.h>
78
79 #define TCPSTATES
80 #include <netinet/tcp_fsm.h>
81 #define TCPTIMERS
82 #include <netinet/tcp_timer.h>
83
84 #include <netns/ns.h>
85 #include <netns/sp.h>
86 #include <netns/idp.h>
87 #include <netns/spidp.h>
88 #include <netns/spp_timer.h>
89 #include <netns/spp_var.h>
90 #include <netns/ns_pcb.h>
91 #include <netns/idp_var.h>
92 #define SANAMES
93 #include <netns/spp_debug.h>
94
95 #include <stdio.h>
96 #include <errno.h>
97 #include <nlist.h>
98 #include <paths.h>
99
100 unsigned long ntime;
101 int sflag;
102 int tflag;
103 int jflag;
104 int aflag;
105 int zflag;
106 int numeric();
107 struct nlist nl[] = {
108 { "_spp_debug" },
109 { "_spp_debx" },
110 0
111 };
112 struct spp_debug spp_debug[SPP_NDEBUG];
113 caddr_t spp_pcbs[SPP_NDEBUG];
114 int spp_debx;
115
116 main(argc, argv)
117 int argc;
118 char **argv;
119 {
120 int i, mask = 0, npcbs = 0;
121 char *system, *core;
122
123 system = _PATH_UNIX;
124 core = _PATH_KMEM;
125
126 argc--, argv++;
127 again:
128 if (argc > 0 && !strcmp(*argv, "-a")) {
129 aflag++, argc--, argv++;
130 goto again;
131 }
132 if (argc > 0 && !strcmp(*argv, "-z")) {
133 zflag++, argc--, argv++;
134 goto again;
135 }
136 if (argc > 0 && !strcmp(*argv, "-s")) {
137 sflag++, argc--, argv++;
138 goto again;
139 }
140 if (argc > 0 && !strcmp(*argv, "-t")) {
141 tflag++, argc--, argv++;
142 goto again;
143 }
144 if (argc > 0 && !strcmp(*argv, "-j")) {
145 jflag++, argc--, argv++;
146 goto again;
147 }
148 if (argc > 0 && !strcmp(*argv, "-p")) {
149 argc--, argv++;
150 if (argc < 1) {
151 fprintf(stderr, "-p: missing sppcb address\n");
152 exit(1);
153 }
154 if (npcbs >= SPP_NDEBUG) {
155 fprintf(stderr, "-p: too many pcb's specified\n");
156 exit(1);
157 }
158 sscanf(*argv, "%x", &spp_pcbs[npcbs++]);
159 argc--, argv++;
160 goto again;
161 }
162 if (argc > 0) {
163 system = *argv;
164 argc--, argv++;
165 mask++;
166 /*
167 * Discard setgid privileges if not the running kernel so that
168 * bad guys can't print interesting stuff from kernel memory.
169 */
170 setgid(getgid());
171 }
172 if (argc > 0) {
173 core = *argv;
174 argc--, argv++;
175 mask++;
176 setgid(getgid());
177 }
178 (void) nlist(system, nl);
179 if (nl[0].n_value == 0) {
180 fprintf(stderr, "trsp: %s: no namelist\n", system);
181 exit(1);
182 }
183 (void) close(0);
184 if (open(core, 0) < 0) {
185 fprintf(stderr, "trsp: "); perror(core);
186 exit(2);
187 }
188 if (mask) {
189 nl[0].n_value &= 0x7fffffff;
190 nl[1].n_value &= 0x7fffffff;
191 }
192 (void) lseek(0, nl[1].n_value, 0);
193 if (read(0, &spp_debx, sizeof (spp_debx)) != sizeof (spp_debx)) {
194 fprintf(stderr, "trsp: "); perror("spp_debx");
195 exit(3);
196 }
197 printf("spp_debx=%d\n", spp_debx);
198 (void) lseek(0, nl[0].n_value, 0);
199 if (read(0, spp_debug, sizeof (spp_debug)) != sizeof (spp_debug)) {
200 fprintf(stderr, "trsp: "); perror("spp_debug");
201 exit(3);
202 }
203 /*
204 * Here, we just want to clear out the old trace data and start over.
205 */
206 if (zflag) {
207 char *cp = (char *) spp_debug,
208 *cplim = cp + sizeof(spp_debug);
209 (void) close(0);
210 if (open(core, 2) < 0) {
211 fprintf(stderr, "trsp: "); perror(core);
212 exit(2);
213 }
214 while(cp < cplim) *cp++ = 0;
215 (void) lseek(0, nl[0].n_value, 0);
216 if (write(0, spp_debug, sizeof (spp_debug)) != sizeof (spp_debug)) {
217 fprintf(stderr, "trsp: "); perror("spp_debug");
218 exit(3);
219 }
220 (void) lseek(0, nl[1].n_value, 0);
221 spp_debx = 0;
222 if (write(0, &spp_debx, sizeof (spp_debx)) != sizeof (spp_debx)) {
223 fprintf(stderr, "trsp: "); perror("spp_debx");
224 exit(3);
225 }
226 exit(0);
227 }
228 /*
229 * If no control blocks have been specified, figure
230 * out how many distinct one we have and summarize
231 * them in spp_pcbs for sorting the trace records
232 * below.
233 */
234 if (npcbs == 0) {
235 for (i = 0; i < SPP_NDEBUG; i++) {
236 register int j;
237 register struct spp_debug *sd = &spp_debug[i];
238
239 if (sd->sd_cb == 0)
240 continue;
241 for (j = 0; j < npcbs; j++)
242 if (spp_pcbs[j] == sd->sd_cb)
243 break;
244 if (j >= npcbs)
245 spp_pcbs[npcbs++] = sd->sd_cb;
246 }
247 }
248 qsort(spp_pcbs, npcbs, sizeof (caddr_t), numeric);
249 if (jflag) {
250 char *cp = "";
251
252 for (i = 0; i < npcbs; i++) {
253 printf("%s%x", cp, spp_pcbs[i]);
254 cp = ", ";
255 }
256 if (*cp)
257 putchar('\n');
258 exit(0);
259 }
260 for (i = 0; i < npcbs; i++) {
261 printf("\n%x:\n", spp_pcbs[i]);
262 dotrace(spp_pcbs[i]);
263 }
264 exit(0);
265 }
266
267 dotrace(sppcb)
268 register caddr_t sppcb;
269 {
270 register int i;
271 register struct spp_debug *sd;
272
273 for (i = spp_debx % SPP_NDEBUG; i < SPP_NDEBUG; i++) {
274 sd = &spp_debug[i];
275 if (sppcb && sd->sd_cb != sppcb)
276 continue;
277 ntime = ntohl(sd->sd_time);
278 spp_trace(sd->sd_act, sd->sd_ostate, sd->sd_cb, &sd->sd_sp,
279 &sd->sd_si, sd->sd_req);
280 }
281 for (i = 0; i < spp_debx % SPP_NDEBUG; i++) {
282 sd = &spp_debug[i];
283 if (sppcb && sd->sd_cb != sppcb)
284 continue;
285 ntime = ntohl(sd->sd_time);
286 spp_trace(sd->sd_act, sd->sd_ostate, sd->sd_cb, &sd->sd_sp,
287 &sd->sd_si, sd->sd_req);
288 }
289 }
290
291 ptime(ms)
292 int ms;
293 {
294
295 printf("%03d ", (ms/10) % 1000);
296 }
297
298 numeric(c1, c2)
299 caddr_t *c1, *c2;
300 {
301
302 return (*c1 - *c2);
303 }
304
305 spp_trace(act, ostate, asp, sp, si, req)
306 short act, ostate;
307 struct sppcb *asp, *sp;
308 struct spidp *si;
309 int req;
310 {
311 u_short seq, ack, len, alo;
312 int flags, timer;
313 char *cp;
314
315 if(ostate >= TCP_NSTATES) ostate = 0;
316 if(act > SA_DROP) act = SA_DROP;
317 printf("\n");
318 ptime(ntime);
319 printf("%s:%s", tcpstates[ostate], sanames[act]);
320
321 if (si != 0) {
322 seq = si->si_seq;
323 ack = si->si_ack;
324 alo = si->si_alo;
325 len = si->si_len;
326 switch (act) {
327 case SA_RESPOND:
328 case SA_OUTPUT:
329 seq = ntohs(seq);
330 ack = ntohs(ack);
331 alo = ntohs(alo);
332 len = ntohs(len);
333 case SA_INPUT:
334 case SA_DROP:
335 if (aflag) {
336 printf("\n\tsna=");
337 ns_printhost(&si->si_sna);
338 printf("\tdna=");
339 ns_printhost(&si->si_dna);
340 }
341 printf("\n\t");
342 #define p1(name, f) { \
343 printf("%s = %x, ", name, f); \
344 }
345 p1("seq", seq);
346 p1("ack", ack);
347 p1("alo", alo);
348 p1("len", len);
349 flags = si->si_cc;
350 printf("flags=%x", flags);
351 #define pf(name, f) { \
352 if (flags & f) { \
353 printf("%s%s", cp, name); \
354 cp = ","; \
355 } \
356 }
357 if (flags) {
358 char *cp = "<";
359 pf("SP_SP", SP_SP);
360 pf("SP_SA", SP_SA);
361 pf("SP_OB", SP_OB);
362 pf("SP_EM", SP_EM);
363 printf(">");
364 }
365 printf(", ");
366 #define p2(name, f) { \
367 printf("%s = %x, ", name, f); \
368 }
369 p2("sid", si->si_sid);
370 p2("did", si->si_did);
371 p2("dt", si->si_dt);
372 printf("\n\tsna=");
373 ns_printhost(&si->si_sna);
374 printf("\tdna=");
375 ns_printhost(&si->si_dna);
376 }
377 }
378 if(act == SA_USER) {
379 printf("\treq=%s", prurequests[req&0xff]);
380 if ((req & 0xff) == PRU_SLOWTIMO)
381 printf("<%s>", tcptimers[req>>8]);
382 }
383 printf(" -> %s", tcpstates[sp->s_state]);
384
385 /* print out internal state of sp !?! */
386 printf("\n");
387 if (sp == 0)
388 return;
389 #define p3(name, f) { \
390 printf("%s = %x, ", name, f); \
391 }
392 if (sflag) {
393 printf("\t");
394 p3("rack", sp->s_rack);
395 p3("ralo", sp->s_ralo);
396 p3("smax", sp->s_smax);
397 p3("snxt", sp->s_snxt);
398 p3("flags", sp->s_flags);
399 #undef pf
400 #define pf(name, f) { \
401 if (flags & f) { \
402 printf("%s%s", cp, name); \
403 cp = ","; \
404 } \
405 }
406 flags = sp->s_flags;
407 if (flags || sp->s_oobflags) {
408 char *cp = "<";
409 pf("ACKNOW", SF_ACKNOW);
410 pf("DELACK", SF_DELACK);
411 pf("HI", SF_HI);
412 pf("HO", SF_HO);
413 pf("PI", SF_PI);
414 pf("WIN", SF_WIN);
415 pf("RXT", SF_RXT);
416 pf("RVD", SF_RVD);
417 flags = sp->s_oobflags;
418 pf("SOOB", SF_SOOB);
419 pf("IOOB", SF_IOOB);
420 printf(">");
421 }
422 }
423 /* print out timers? */
424 if (tflag) {
425 char *cp = "\t";
426 register int i;
427
428 printf("\n\tTIMERS: ");
429 p3("idle", sp->s_idle);
430 p3("force", sp->s_force);
431 p3("rtseq", sp->s_rtseq);
432 for (i = 0; i < TCPT_NTIMERS; i++) {
433 if (sp->s_timer[i] == 0)
434 continue;
435 printf("%s%s=%d", cp, tcptimers[i], sp->s_timer[i]);
436 if (i == TCPT_REXMT)
437 printf(" (s_rxtshft=%d)", sp->s_rxtshift);
438 cp = ", ";
439 }
440 if (*cp != '\t')
441 putchar('\n');
442 }
443 }
444
445 ns_printhost(p)
446 register struct ns_addr *p;
447 {
448
449 printf("<net:%x%x,host:%4.4x%4.4x%4.4x,port:%x>",
450 p->x_net.s_net[0],
451 p->x_net.s_net[1],
452 p->x_host.s_host[0],
453 p->x_host.s_host[1],
454 p->x_host.s_host[2],
455 p->x_port);
456
457 }
458