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