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*37985Sbostic static char sccsid[] = "@(#)trsp.c 6.5 (Berkeley) 05/11/89"; 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> 4835616Sbostic #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> 56*37985Sbostic #include <paths.h> 5725117Ssklower 5825117Ssklower unsigned long ntime; 5925117Ssklower int sflag; 6025117Ssklower int tflag; 6125117Ssklower int jflag; 6225117Ssklower int aflag; 6325117Ssklower int zflag; 6425117Ssklower int numeric(); 6525117Ssklower struct nlist nl[] = { 6625117Ssklower { "_spp_debug" }, 6725117Ssklower { "_spp_debx" }, 6825117Ssklower 0 6925117Ssklower }; 7025117Ssklower struct spp_debug spp_debug[SPP_NDEBUG]; 7125117Ssklower caddr_t spp_pcbs[SPP_NDEBUG]; 7225117Ssklower int spp_debx; 7325117Ssklower 7425117Ssklower main(argc, argv) 7525117Ssklower int argc; 7625117Ssklower char **argv; 7725117Ssklower { 7825117Ssklower int i, mask = 0, npcbs = 0; 7937309Sbostic char *system, *core; 8025117Ssklower 8137309Sbostic system = _PATH_UNIX; 8237309Sbostic core = _PATH_KMEM; 8337309Sbostic 8425117Ssklower argc--, argv++; 8525117Ssklower again: 8625117Ssklower if (argc > 0 && !strcmp(*argv, "-a")) { 8725117Ssklower aflag++, argc--, argv++; 8825117Ssklower goto again; 8925117Ssklower } 9025117Ssklower if (argc > 0 && !strcmp(*argv, "-z")) { 9125117Ssklower zflag++, argc--, argv++; 9225117Ssklower goto again; 9325117Ssklower } 9425117Ssklower if (argc > 0 && !strcmp(*argv, "-s")) { 9525117Ssklower sflag++, argc--, argv++; 9625117Ssklower goto again; 9725117Ssklower } 9825117Ssklower if (argc > 0 && !strcmp(*argv, "-t")) { 9925117Ssklower tflag++, argc--, argv++; 10025117Ssklower goto again; 10125117Ssklower } 10225117Ssklower if (argc > 0 && !strcmp(*argv, "-j")) { 10325117Ssklower jflag++, argc--, argv++; 10425117Ssklower goto again; 10525117Ssklower } 10625117Ssklower if (argc > 0 && !strcmp(*argv, "-p")) { 10725117Ssklower argc--, argv++; 10825117Ssklower if (argc < 1) { 10925117Ssklower fprintf(stderr, "-p: missing sppcb address\n"); 11025117Ssklower exit(1); 11125117Ssklower } 11225117Ssklower if (npcbs >= SPP_NDEBUG) { 11325117Ssklower fprintf(stderr, "-p: too many pcb's specified\n"); 11425117Ssklower exit(1); 11525117Ssklower } 11625117Ssklower sscanf(*argv, "%x", &spp_pcbs[npcbs++]); 11725117Ssklower argc--, argv++; 11825117Ssklower goto again; 11925117Ssklower } 12025117Ssklower if (argc > 0) { 12125117Ssklower system = *argv; 12225117Ssklower argc--, argv++; 12325117Ssklower mask++; 12425117Ssklower } 12525117Ssklower if (argc > 0) { 12625117Ssklower core = *argv; 12725117Ssklower argc--, argv++; 12825117Ssklower mask++; 12925117Ssklower } 13025117Ssklower (void) nlist(system, nl); 13125117Ssklower if (nl[0].n_value == 0) { 13225117Ssklower fprintf(stderr, "trsp: %s: no namelist\n", system); 13325117Ssklower exit(1); 13425117Ssklower } 13525117Ssklower (void) close(0); 13625117Ssklower if (open(core, 0) < 0) { 13725117Ssklower fprintf(stderr, "trsp: "); perror(core); 13825117Ssklower exit(2); 13925117Ssklower } 14025117Ssklower if (mask) { 14125117Ssklower nl[0].n_value &= 0x7fffffff; 14225117Ssklower nl[1].n_value &= 0x7fffffff; 14325117Ssklower } 14425117Ssklower (void) lseek(0, nl[1].n_value, 0); 14525117Ssklower if (read(0, &spp_debx, sizeof (spp_debx)) != sizeof (spp_debx)) { 14625117Ssklower fprintf(stderr, "trsp: "); perror("spp_debx"); 14725117Ssklower exit(3); 14825117Ssklower } 14925117Ssklower printf("spp_debx=%d\n", spp_debx); 15025117Ssklower (void) lseek(0, nl[0].n_value, 0); 15125117Ssklower if (read(0, spp_debug, sizeof (spp_debug)) != sizeof (spp_debug)) { 15225117Ssklower fprintf(stderr, "trsp: "); perror("spp_debug"); 15325117Ssklower exit(3); 15425117Ssklower } 15525117Ssklower /* 15625117Ssklower * Here, we just want to clear out the old trace data and start over. 15725117Ssklower */ 15825117Ssklower if (zflag) { 15925117Ssklower char *cp = (char *) spp_debug, 16025117Ssklower *cplim = cp + sizeof(spp_debug); 16125117Ssklower (void) close(0); 16225117Ssklower if (open(core, 2) < 0) { 16325117Ssklower fprintf(stderr, "trsp: "); perror(core); 16425117Ssklower exit(2); 16525117Ssklower } 16625117Ssklower while(cp < cplim) *cp++ = 0; 16725117Ssklower (void) lseek(0, nl[0].n_value, 0); 16825117Ssklower if (write(0, spp_debug, sizeof (spp_debug)) != sizeof (spp_debug)) { 16925117Ssklower fprintf(stderr, "trsp: "); perror("spp_debug"); 17025117Ssklower exit(3); 17125117Ssklower } 17225117Ssklower (void) lseek(0, nl[1].n_value, 0); 17325117Ssklower spp_debx = 0; 17425117Ssklower if (write(0, &spp_debx, sizeof (spp_debx)) != sizeof (spp_debx)) { 17525117Ssklower fprintf(stderr, "trsp: "); perror("spp_debx"); 17625117Ssklower exit(3); 17725117Ssklower } 17825117Ssklower exit(0); 17925117Ssklower } 18025117Ssklower /* 18125117Ssklower * If no control blocks have been specified, figure 18225117Ssklower * out how many distinct one we have and summarize 18325117Ssklower * them in spp_pcbs for sorting the trace records 18425117Ssklower * below. 18525117Ssklower */ 18625117Ssklower if (npcbs == 0) { 18725117Ssklower for (i = 0; i < SPP_NDEBUG; i++) { 18825117Ssklower register int j; 18925117Ssklower register struct spp_debug *sd = &spp_debug[i]; 19025117Ssklower 19125117Ssklower if (sd->sd_cb == 0) 19225117Ssklower continue; 19325117Ssklower for (j = 0; j < npcbs; j++) 19425117Ssklower if (spp_pcbs[j] == sd->sd_cb) 19525117Ssklower break; 19625117Ssklower if (j >= npcbs) 19725117Ssklower spp_pcbs[npcbs++] = sd->sd_cb; 19825117Ssklower } 19925117Ssklower } 20025117Ssklower qsort(spp_pcbs, npcbs, sizeof (caddr_t), numeric); 20125117Ssklower if (jflag) { 20225117Ssklower char *cp = ""; 20325117Ssklower 20425117Ssklower for (i = 0; i < npcbs; i++) { 20525117Ssklower printf("%s%x", cp, spp_pcbs[i]); 20625117Ssklower cp = ", "; 20725117Ssklower } 20825117Ssklower if (*cp) 20925117Ssklower putchar('\n'); 21025117Ssklower exit(0); 21125117Ssklower } 21225117Ssklower for (i = 0; i < npcbs; i++) { 21325117Ssklower printf("\n%x:\n", spp_pcbs[i]); 21425117Ssklower dotrace(spp_pcbs[i]); 21525117Ssklower } 21625117Ssklower exit(0); 21725117Ssklower } 21825117Ssklower 21925117Ssklower dotrace(sppcb) 22025117Ssklower register caddr_t sppcb; 22125117Ssklower { 22225117Ssklower register int i; 22325117Ssklower register struct spp_debug *sd; 22425117Ssklower 22525117Ssklower for (i = spp_debx % SPP_NDEBUG; i < SPP_NDEBUG; i++) { 22625117Ssklower sd = &spp_debug[i]; 22725117Ssklower if (sppcb && sd->sd_cb != sppcb) 22825117Ssklower continue; 22925117Ssklower ntime = ntohl(sd->sd_time); 23025117Ssklower spp_trace(sd->sd_act, sd->sd_ostate, sd->sd_cb, &sd->sd_sp, 23125117Ssklower &sd->sd_si, sd->sd_req); 23225117Ssklower } 23325117Ssklower for (i = 0; i < spp_debx % SPP_NDEBUG; i++) { 23425117Ssklower sd = &spp_debug[i]; 23525117Ssklower if (sppcb && sd->sd_cb != sppcb) 23625117Ssklower continue; 23725117Ssklower ntime = ntohl(sd->sd_time); 23825117Ssklower spp_trace(sd->sd_act, sd->sd_ostate, sd->sd_cb, &sd->sd_sp, 23925117Ssklower &sd->sd_si, sd->sd_req); 24025117Ssklower } 24125117Ssklower } 24225117Ssklower 24325117Ssklower ptime(ms) 24425117Ssklower int ms; 24525117Ssklower { 24625117Ssklower 24725117Ssklower printf("%03d ", (ms/10) % 1000); 24825117Ssklower } 24925117Ssklower 25025117Ssklower numeric(c1, c2) 25125117Ssklower caddr_t *c1, *c2; 25225117Ssklower { 25325117Ssklower 25425117Ssklower return (*c1 - *c2); 25525117Ssklower } 25625117Ssklower 25725117Ssklower spp_trace(act, ostate, asp, sp, si, req) 25825117Ssklower short act, ostate; 25925117Ssklower struct sppcb *asp, *sp; 26025117Ssklower struct spidp *si; 26125117Ssklower int req; 26225117Ssklower { 26325117Ssklower u_short seq, ack, len, alo; 26425117Ssklower int flags, timer; 26525117Ssklower char *cp; 26625117Ssklower 26725117Ssklower if(ostate >= TCP_NSTATES) ostate = 0; 26825117Ssklower if(act > SA_DROP) act = SA_DROP; 26925117Ssklower printf("\n"); 27025117Ssklower ptime(ntime); 27125117Ssklower printf("%s:%s", tcpstates[ostate], sanames[act]); 27225117Ssklower 27325117Ssklower if (si != 0) { 27425117Ssklower seq = si->si_seq; 27525117Ssklower ack = si->si_ack; 27625117Ssklower alo = si->si_alo; 27725117Ssklower len = si->si_len; 27825117Ssklower switch (act) { 27925117Ssklower case SA_RESPOND: 28025117Ssklower case SA_OUTPUT: 28125117Ssklower seq = ntohs(seq); 28225117Ssklower ack = ntohs(ack); 28325117Ssklower alo = ntohs(alo); 28425117Ssklower len = ntohs(len); 28525117Ssklower case SA_INPUT: 28625117Ssklower case SA_DROP: 28725117Ssklower if (aflag) { 28825117Ssklower printf("\n\tsna="); 28925117Ssklower ns_printhost(&si->si_sna); 29025117Ssklower printf("\tdna="); 29125117Ssklower ns_printhost(&si->si_dna); 29225117Ssklower } 29325117Ssklower printf("\n\t"); 29425117Ssklower #define p1(f) { printf("%s = %x, ", "f", f); } 29525117Ssklower p1(seq); p1(ack); p1(alo); p1(len); 29625117Ssklower flags = si->si_cc; 29725117Ssklower printf("flags=%x", flags); 29825117Ssklower if (flags) { 29925117Ssklower char *cp = "<"; 30025117Ssklower #define pf(f) { if (flags&SP_/**/f) { printf("%s%s", cp, "f"); cp = ","; } } 30125117Ssklower pf(SP); pf(SA); pf(OB); pf(EM); 30225117Ssklower printf(">"); 30325117Ssklower } 30425117Ssklower printf(", "); 30525117Ssklower #define p2(f) { printf("%s = %x, ", "f", si->si_/**/f); } 30625117Ssklower p2(sid);p2(did);p2(dt); 30725117Ssklower printf("\n\tsna="); 30825117Ssklower ns_printhost(&si->si_sna); 30925117Ssklower printf("\tdna="); 31025117Ssklower ns_printhost(&si->si_dna); 31125117Ssklower } 31225117Ssklower } 31325117Ssklower if(act == SA_USER) { 31425117Ssklower printf("\treq=%s", prurequests[req&0xff]); 31525117Ssklower if ((req & 0xff) == PRU_SLOWTIMO) 31625117Ssklower printf("<%s>", tcptimers[req>>8]); 31725117Ssklower } 31825117Ssklower printf(" -> %s", tcpstates[sp->s_state]); 31925117Ssklower 32025117Ssklower /* print out internal state of sp !?! */ 32125117Ssklower printf("\n"); 32225117Ssklower if (sp == 0) 32325117Ssklower return; 32425117Ssklower #define p3(f) { printf("%s = %x, ", "f", sp->s_/**/f); } 32525117Ssklower if(sflag) { 32635616Sbostic printf("\t"); p3(rack); p3(ralo); p3(smax); p3(snxt); p3(flags); 32725117Ssklower #undef pf 32825117Ssklower #define pf(f) { if (flags&SF_/**/f) { printf("%s%s", cp, "f"); cp = ","; } } 32925117Ssklower flags = sp->s_flags; 33025117Ssklower if (flags || sp->s_oobflags) { 33125117Ssklower char *cp = "<"; 33235616Sbostic pf(ACKNOW); pf(DELACK); pf(HI); pf(HO); 33335616Sbostic pf(PI); pf(WIN); pf(RXT); pf(RVD); 33425117Ssklower flags = sp->s_oobflags; 33525117Ssklower pf(SOOB); pf(IOOB); 33625117Ssklower printf(">"); 33725117Ssklower } 33825117Ssklower 33925117Ssklower } 34025117Ssklower /* print out timers? */ 34125117Ssklower if (tflag) { 34225117Ssklower char *cp = "\t"; 34325117Ssklower register int i; 34425117Ssklower 34525117Ssklower printf("\n\tTIMERS: "); 34625117Ssklower p3(idle); p3(force); p3(rtseq); 34725117Ssklower for (i = 0; i < TCPT_NTIMERS; i++) { 34825117Ssklower if (sp->s_timer[i] == 0) 34925117Ssklower continue; 35025117Ssklower printf("%s%s=%d", cp, tcptimers[i], sp->s_timer[i]); 35125117Ssklower if (i == TCPT_REXMT) 35225117Ssklower printf(" (s_rxtshft=%d)", sp->s_rxtshift); 35325117Ssklower cp = ", "; 35425117Ssklower } 35525117Ssklower if (*cp != '\t') 35625117Ssklower putchar('\n'); 35725117Ssklower } 35825117Ssklower } 35925117Ssklower 36025117Ssklower ns_printhost(p) 36125117Ssklower register struct ns_addr *p; 36225117Ssklower { 36325117Ssklower 36425117Ssklower printf("<net:%x%x,host:%4.4x%4.4x%4.4x,port:%x>", 36525117Ssklower p->x_net.s_net[0], 36625117Ssklower p->x_net.s_net[1], 36725117Ssklower p->x_host.s_host[0], 36825117Ssklower p->x_host.s_host[1], 36925117Ssklower p->x_host.s_host[2], 37025117Ssklower p->x_port); 37125117Ssklower 37225117Ssklower } 37325117Ssklower 374