125117Ssklower /* 225117Ssklower * Copyright (c) 1985 Regents of the University of California. 3*34940Sbostic * All rights reserved. 4*34940Sbostic * 5*34940Sbostic * Redistribution and use in source and binary forms are permitted 6*34940Sbostic * provided that the above copyright notice and this paragraph are 7*34940Sbostic * duplicated in all such forms and that any documentation, 8*34940Sbostic * advertising materials, and other materials related to such 9*34940Sbostic * distribution and use acknowledge that the software was developed 10*34940Sbostic * by the University of California, Berkeley. The name of the 11*34940Sbostic * University may not be used to endorse or promote products derived 12*34940Sbostic * from this software without specific prior written permission. 13*34940Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 14*34940Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 15*34940Sbostic * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1625117Ssklower */ 1725117Ssklower 1825117Ssklower #ifndef lint 1925117Ssklower char copyright[] = 20*34940Sbostic "@(#) Copyright (c) 1985 Regents of the University of California.\n\ 2125117Ssklower All rights reserved.\n"; 22*34940Sbostic #endif /* not lint */ 2325117Ssklower 2425117Ssklower #ifndef lint 25*34940Sbostic static char sccsid[] = "@(#)trsp.c 6.2 (Berkeley) 07/01/88"; 26*34940Sbostic #endif /* not lint */ 2725117Ssklower 2825117Ssklower #include <sys/param.h> 2925117Ssklower #include <sys/socket.h> 3025117Ssklower #include <sys/socketvar.h> 3125117Ssklower #define PRUREQUESTS 3225117Ssklower #include <sys/protosw.h> 3325117Ssklower 3425117Ssklower #include <net/route.h> 3525117Ssklower #include <net/if.h> 3625117Ssklower 3725117Ssklower #define TCPSTATES 3825117Ssklower #include <netinet/tcp_fsm.h> 3925117Ssklower #define TCPTIMERS 4025117Ssklower #include <netinet/tcp_timer.h> 4125117Ssklower 4225117Ssklower #include <netns/ns.h> 4325117Ssklower #include <netns/ns_pcb.h> 4425117Ssklower #include <netns/idp.h> 4525117Ssklower #include <netns/idp_var.h> 4625117Ssklower #include <netns/sp.h> 4725117Ssklower #include <netns/spidp.h> 4825117Ssklower #include <netns/spp_var.h> 4925117Ssklower #define SANAMES 5025117Ssklower #include <netns/spp_debug.h> 5125117Ssklower 5225117Ssklower #include <stdio.h> 5325117Ssklower #include <errno.h> 5425117Ssklower #include <nlist.h> 5525117Ssklower 5625117Ssklower unsigned long ntime; 5725117Ssklower int sflag; 5825117Ssklower int tflag; 5925117Ssklower int jflag; 6025117Ssklower int aflag; 6125117Ssklower int zflag; 6225117Ssklower int numeric(); 6325117Ssklower struct nlist nl[] = { 6425117Ssklower { "_spp_debug" }, 6525117Ssklower { "_spp_debx" }, 6625117Ssklower 0 6725117Ssklower }; 6825117Ssklower struct spp_debug spp_debug[SPP_NDEBUG]; 6925117Ssklower caddr_t spp_pcbs[SPP_NDEBUG]; 7025117Ssklower int spp_debx; 7125117Ssklower 7225117Ssklower main(argc, argv) 7325117Ssklower int argc; 7425117Ssklower char **argv; 7525117Ssklower { 7625117Ssklower int i, mask = 0, npcbs = 0; 7725117Ssklower char *system = "/vmunix", *core = "/dev/kmem"; 7825117Ssklower 7925117Ssklower argc--, argv++; 8025117Ssklower again: 8125117Ssklower if (argc > 0 && !strcmp(*argv, "-a")) { 8225117Ssklower aflag++, argc--, argv++; 8325117Ssklower goto again; 8425117Ssklower } 8525117Ssklower if (argc > 0 && !strcmp(*argv, "-z")) { 8625117Ssklower zflag++, argc--, argv++; 8725117Ssklower goto again; 8825117Ssklower } 8925117Ssklower if (argc > 0 && !strcmp(*argv, "-s")) { 9025117Ssklower sflag++, argc--, argv++; 9125117Ssklower goto again; 9225117Ssklower } 9325117Ssklower if (argc > 0 && !strcmp(*argv, "-t")) { 9425117Ssklower tflag++, argc--, argv++; 9525117Ssklower goto again; 9625117Ssklower } 9725117Ssklower if (argc > 0 && !strcmp(*argv, "-j")) { 9825117Ssklower jflag++, argc--, argv++; 9925117Ssklower goto again; 10025117Ssklower } 10125117Ssklower if (argc > 0 && !strcmp(*argv, "-p")) { 10225117Ssklower argc--, argv++; 10325117Ssklower if (argc < 1) { 10425117Ssklower fprintf(stderr, "-p: missing sppcb address\n"); 10525117Ssklower exit(1); 10625117Ssklower } 10725117Ssklower if (npcbs >= SPP_NDEBUG) { 10825117Ssklower fprintf(stderr, "-p: too many pcb's specified\n"); 10925117Ssklower exit(1); 11025117Ssklower } 11125117Ssklower sscanf(*argv, "%x", &spp_pcbs[npcbs++]); 11225117Ssklower argc--, argv++; 11325117Ssklower goto again; 11425117Ssklower } 11525117Ssklower if (argc > 0) { 11625117Ssklower system = *argv; 11725117Ssklower argc--, argv++; 11825117Ssklower mask++; 11925117Ssklower } 12025117Ssklower if (argc > 0) { 12125117Ssklower core = *argv; 12225117Ssklower argc--, argv++; 12325117Ssklower mask++; 12425117Ssklower } 12525117Ssklower (void) nlist(system, nl); 12625117Ssklower if (nl[0].n_value == 0) { 12725117Ssklower fprintf(stderr, "trsp: %s: no namelist\n", system); 12825117Ssklower exit(1); 12925117Ssklower } 13025117Ssklower (void) close(0); 13125117Ssklower if (open(core, 0) < 0) { 13225117Ssklower fprintf(stderr, "trsp: "); perror(core); 13325117Ssklower exit(2); 13425117Ssklower } 13525117Ssklower if (mask) { 13625117Ssklower nl[0].n_value &= 0x7fffffff; 13725117Ssklower nl[1].n_value &= 0x7fffffff; 13825117Ssklower } 13925117Ssklower (void) lseek(0, nl[1].n_value, 0); 14025117Ssklower if (read(0, &spp_debx, sizeof (spp_debx)) != sizeof (spp_debx)) { 14125117Ssklower fprintf(stderr, "trsp: "); perror("spp_debx"); 14225117Ssklower exit(3); 14325117Ssklower } 14425117Ssklower printf("spp_debx=%d\n", spp_debx); 14525117Ssklower (void) lseek(0, nl[0].n_value, 0); 14625117Ssklower if (read(0, spp_debug, sizeof (spp_debug)) != sizeof (spp_debug)) { 14725117Ssklower fprintf(stderr, "trsp: "); perror("spp_debug"); 14825117Ssklower exit(3); 14925117Ssklower } 15025117Ssklower /* 15125117Ssklower * Here, we just want to clear out the old trace data and start over. 15225117Ssklower */ 15325117Ssklower if (zflag) { 15425117Ssklower char *cp = (char *) spp_debug, 15525117Ssklower *cplim = cp + sizeof(spp_debug); 15625117Ssklower (void) close(0); 15725117Ssklower if (open(core, 2) < 0) { 15825117Ssklower fprintf(stderr, "trsp: "); perror(core); 15925117Ssklower exit(2); 16025117Ssklower } 16125117Ssklower while(cp < cplim) *cp++ = 0; 16225117Ssklower (void) lseek(0, nl[0].n_value, 0); 16325117Ssklower if (write(0, spp_debug, sizeof (spp_debug)) != sizeof (spp_debug)) { 16425117Ssklower fprintf(stderr, "trsp: "); perror("spp_debug"); 16525117Ssklower exit(3); 16625117Ssklower } 16725117Ssklower (void) lseek(0, nl[1].n_value, 0); 16825117Ssklower spp_debx = 0; 16925117Ssklower if (write(0, &spp_debx, sizeof (spp_debx)) != sizeof (spp_debx)) { 17025117Ssklower fprintf(stderr, "trsp: "); perror("spp_debx"); 17125117Ssklower exit(3); 17225117Ssklower } 17325117Ssklower exit(0); 17425117Ssklower } 17525117Ssklower /* 17625117Ssklower * If no control blocks have been specified, figure 17725117Ssklower * out how many distinct one we have and summarize 17825117Ssklower * them in spp_pcbs for sorting the trace records 17925117Ssklower * below. 18025117Ssklower */ 18125117Ssklower if (npcbs == 0) { 18225117Ssklower for (i = 0; i < SPP_NDEBUG; i++) { 18325117Ssklower register int j; 18425117Ssklower register struct spp_debug *sd = &spp_debug[i]; 18525117Ssklower 18625117Ssklower if (sd->sd_cb == 0) 18725117Ssklower continue; 18825117Ssklower for (j = 0; j < npcbs; j++) 18925117Ssklower if (spp_pcbs[j] == sd->sd_cb) 19025117Ssklower break; 19125117Ssklower if (j >= npcbs) 19225117Ssklower spp_pcbs[npcbs++] = sd->sd_cb; 19325117Ssklower } 19425117Ssklower } 19525117Ssklower qsort(spp_pcbs, npcbs, sizeof (caddr_t), numeric); 19625117Ssklower if (jflag) { 19725117Ssklower char *cp = ""; 19825117Ssklower 19925117Ssklower for (i = 0; i < npcbs; i++) { 20025117Ssklower printf("%s%x", cp, spp_pcbs[i]); 20125117Ssklower cp = ", "; 20225117Ssklower } 20325117Ssklower if (*cp) 20425117Ssklower putchar('\n'); 20525117Ssklower exit(0); 20625117Ssklower } 20725117Ssklower for (i = 0; i < npcbs; i++) { 20825117Ssklower printf("\n%x:\n", spp_pcbs[i]); 20925117Ssklower dotrace(spp_pcbs[i]); 21025117Ssklower } 21125117Ssklower exit(0); 21225117Ssklower } 21325117Ssklower 21425117Ssklower dotrace(sppcb) 21525117Ssklower register caddr_t sppcb; 21625117Ssklower { 21725117Ssklower register int i; 21825117Ssklower register struct spp_debug *sd; 21925117Ssklower 22025117Ssklower for (i = spp_debx % SPP_NDEBUG; i < SPP_NDEBUG; i++) { 22125117Ssklower sd = &spp_debug[i]; 22225117Ssklower if (sppcb && sd->sd_cb != sppcb) 22325117Ssklower continue; 22425117Ssklower ntime = ntohl(sd->sd_time); 22525117Ssklower spp_trace(sd->sd_act, sd->sd_ostate, sd->sd_cb, &sd->sd_sp, 22625117Ssklower &sd->sd_si, sd->sd_req); 22725117Ssklower } 22825117Ssklower for (i = 0; i < spp_debx % SPP_NDEBUG; i++) { 22925117Ssklower sd = &spp_debug[i]; 23025117Ssklower if (sppcb && sd->sd_cb != sppcb) 23125117Ssklower continue; 23225117Ssklower ntime = ntohl(sd->sd_time); 23325117Ssklower spp_trace(sd->sd_act, sd->sd_ostate, sd->sd_cb, &sd->sd_sp, 23425117Ssklower &sd->sd_si, sd->sd_req); 23525117Ssklower } 23625117Ssklower } 23725117Ssklower 23825117Ssklower ptime(ms) 23925117Ssklower int ms; 24025117Ssklower { 24125117Ssklower 24225117Ssklower printf("%03d ", (ms/10) % 1000); 24325117Ssklower } 24425117Ssklower 24525117Ssklower numeric(c1, c2) 24625117Ssklower caddr_t *c1, *c2; 24725117Ssklower { 24825117Ssklower 24925117Ssklower return (*c1 - *c2); 25025117Ssklower } 25125117Ssklower 25225117Ssklower spp_trace(act, ostate, asp, sp, si, req) 25325117Ssklower short act, ostate; 25425117Ssklower struct sppcb *asp, *sp; 25525117Ssklower struct spidp *si; 25625117Ssklower int req; 25725117Ssklower { 25825117Ssklower u_short seq, ack, len, alo; 25925117Ssklower int flags, timer; 26025117Ssklower char *cp; 26125117Ssklower 26225117Ssklower if(ostate >= TCP_NSTATES) ostate = 0; 26325117Ssklower if(act > SA_DROP) act = SA_DROP; 26425117Ssklower printf("\n"); 26525117Ssklower ptime(ntime); 26625117Ssklower printf("%s:%s", tcpstates[ostate], sanames[act]); 26725117Ssklower 26825117Ssklower if (si != 0) { 26925117Ssklower seq = si->si_seq; 27025117Ssklower ack = si->si_ack; 27125117Ssklower alo = si->si_alo; 27225117Ssklower len = si->si_len; 27325117Ssklower switch (act) { 27425117Ssklower case SA_RESPOND: 27525117Ssklower case SA_OUTPUT: 27625117Ssklower seq = ntohs(seq); 27725117Ssklower ack = ntohs(ack); 27825117Ssklower alo = ntohs(alo); 27925117Ssklower len = ntohs(len); 28025117Ssklower case SA_INPUT: 28125117Ssklower case SA_DROP: 28225117Ssklower if (aflag) { 28325117Ssklower printf("\n\tsna="); 28425117Ssklower ns_printhost(&si->si_sna); 28525117Ssklower printf("\tdna="); 28625117Ssklower ns_printhost(&si->si_dna); 28725117Ssklower } 28825117Ssklower printf("\n\t"); 28925117Ssklower #define p1(f) { printf("%s = %x, ", "f", f); } 29025117Ssklower p1(seq); p1(ack); p1(alo); p1(len); 29125117Ssklower flags = si->si_cc; 29225117Ssklower printf("flags=%x", flags); 29325117Ssklower if (flags) { 29425117Ssklower char *cp = "<"; 29525117Ssklower #define pf(f) { if (flags&SP_/**/f) { printf("%s%s", cp, "f"); cp = ","; } } 29625117Ssklower pf(SP); pf(SA); pf(OB); pf(EM); 29725117Ssklower printf(">"); 29825117Ssklower } 29925117Ssklower printf(", "); 30025117Ssklower #define p2(f) { printf("%s = %x, ", "f", si->si_/**/f); } 30125117Ssklower p2(sid);p2(did);p2(dt); 30225117Ssklower printf("\n\tsna="); 30325117Ssklower ns_printhost(&si->si_sna); 30425117Ssklower printf("\tdna="); 30525117Ssklower ns_printhost(&si->si_dna); 30625117Ssklower } 30725117Ssklower } 30825117Ssklower if(act == SA_USER) { 30925117Ssklower printf("\treq=%s", prurequests[req&0xff]); 31025117Ssklower if ((req & 0xff) == PRU_SLOWTIMO) 31125117Ssklower printf("<%s>", tcptimers[req>>8]); 31225117Ssklower } 31325117Ssklower printf(" -> %s", tcpstates[sp->s_state]); 31425117Ssklower 31525117Ssklower /* print out internal state of sp !?! */ 31625117Ssklower printf("\n"); 31725117Ssklower if (sp == 0) 31825117Ssklower return; 31925117Ssklower #define p3(f) { printf("%s = %x, ", "f", sp->s_/**/f); } 32025117Ssklower if(sflag) { 32125117Ssklower printf("\t"); p3(rack); p3(ralo); p3(snt); p3(flags); 32225117Ssklower #undef pf 32325117Ssklower #define pf(f) { if (flags&SF_/**/f) { printf("%s%s", cp, "f"); cp = ","; } } 32425117Ssklower flags = sp->s_flags; 32525117Ssklower if (flags || sp->s_oobflags) { 32625117Ssklower char *cp = "<"; 32725117Ssklower pf(AK); pf(DELACK); pf(HI); pf(HO); 32825117Ssklower flags = sp->s_oobflags; 32925117Ssklower pf(SOOB); pf(IOOB); 33025117Ssklower printf(">"); 33125117Ssklower } 33225117Ssklower 33325117Ssklower } 33425117Ssklower /* print out timers? */ 33525117Ssklower if (tflag) { 33625117Ssklower char *cp = "\t"; 33725117Ssklower register int i; 33825117Ssklower 33925117Ssklower printf("\n\tTIMERS: "); 34025117Ssklower p3(idle); p3(force); p3(rtseq); 34125117Ssklower for (i = 0; i < TCPT_NTIMERS; i++) { 34225117Ssklower if (sp->s_timer[i] == 0) 34325117Ssklower continue; 34425117Ssklower printf("%s%s=%d", cp, tcptimers[i], sp->s_timer[i]); 34525117Ssklower if (i == TCPT_REXMT) 34625117Ssklower printf(" (s_rxtshft=%d)", sp->s_rxtshift); 34725117Ssklower cp = ", "; 34825117Ssklower } 34925117Ssklower if (*cp != '\t') 35025117Ssklower putchar('\n'); 35125117Ssklower } 35225117Ssklower } 35325117Ssklower 35425117Ssklower ns_printhost(p) 35525117Ssklower register struct ns_addr *p; 35625117Ssklower { 35725117Ssklower 35825117Ssklower printf("<net:%x%x,host:%4.4x%4.4x%4.4x,port:%x>", 35925117Ssklower p->x_net.s_net[0], 36025117Ssklower p->x_net.s_net[1], 36125117Ssklower p->x_host.s_host[0], 36225117Ssklower p->x_host.s_host[1], 36325117Ssklower p->x_host.s_host[2], 36425117Ssklower p->x_port); 36525117Ssklower 36625117Ssklower } 36725117Ssklower 368