125117Ssklower /* 225117Ssklower * Copyright (c) 1985 Regents of the University of California. 334940Sbostic * All rights reserved. 434940Sbostic * 542829Sbostic * %sccs.include.redist.c% 625117Ssklower */ 725117Ssklower 825117Ssklower #ifndef lint 925117Ssklower char copyright[] = 1034940Sbostic "@(#) Copyright (c) 1985 Regents of the University of California.\n\ 1125117Ssklower All rights reserved.\n"; 1234940Sbostic #endif /* not lint */ 1325117Ssklower 1425117Ssklower #ifndef lint 15*52256Sbostic static char sccsid[] = "@(#)trsp.c 6.9 (Berkeley) 01/28/92"; 1634940Sbostic #endif /* not lint */ 1725117Ssklower 1846933Sbostic #include <sys/cdefs.h> 1925117Ssklower #include <sys/param.h> 2025117Ssklower #include <sys/socket.h> 2125117Ssklower #include <sys/socketvar.h> 2225117Ssklower #define PRUREQUESTS 2325117Ssklower #include <sys/protosw.h> 2425117Ssklower 2525117Ssklower #include <net/route.h> 2625117Ssklower #include <net/if.h> 2725117Ssklower 2825117Ssklower #define TCPSTATES 2925117Ssklower #include <netinet/tcp_fsm.h> 3025117Ssklower #define TCPTIMERS 3125117Ssklower #include <netinet/tcp_timer.h> 3225117Ssklower 3325117Ssklower #include <netns/ns.h> 3446933Sbostic #include <netns/sp.h> 3525117Ssklower #include <netns/idp.h> 3625117Ssklower #include <netns/spidp.h> 3735616Sbostic #include <netns/spp_timer.h> 3825117Ssklower #include <netns/spp_var.h> 3946933Sbostic #include <netns/ns_pcb.h> 4046933Sbostic #include <netns/idp_var.h> 4125117Ssklower #define SANAMES 4225117Ssklower #include <netns/spp_debug.h> 4325117Ssklower 4425117Ssklower #include <stdio.h> 4525117Ssklower #include <errno.h> 4625117Ssklower #include <nlist.h> 4737985Sbostic #include <paths.h> 4825117Ssklower 4925117Ssklower unsigned long ntime; 5025117Ssklower int sflag; 5125117Ssklower int tflag; 5225117Ssklower int jflag; 5325117Ssklower int aflag; 5425117Ssklower int zflag; 5525117Ssklower int numeric(); 5625117Ssklower struct nlist nl[] = { 5725117Ssklower { "_spp_debug" }, 5825117Ssklower { "_spp_debx" }, 5925117Ssklower 0 6025117Ssklower }; 6125117Ssklower struct spp_debug spp_debug[SPP_NDEBUG]; 6225117Ssklower caddr_t spp_pcbs[SPP_NDEBUG]; 6325117Ssklower int spp_debx; 6425117Ssklower 6525117Ssklower main(argc, argv) 6625117Ssklower int argc; 6725117Ssklower char **argv; 6825117Ssklower { 6925117Ssklower int i, mask = 0, npcbs = 0; 7037309Sbostic char *system, *core; 7125117Ssklower 7237309Sbostic system = _PATH_UNIX; 7337309Sbostic core = _PATH_KMEM; 7437309Sbostic 7525117Ssklower argc--, argv++; 7625117Ssklower again: 7725117Ssklower if (argc > 0 && !strcmp(*argv, "-a")) { 7825117Ssklower aflag++, argc--, argv++; 7925117Ssklower goto again; 8025117Ssklower } 8125117Ssklower if (argc > 0 && !strcmp(*argv, "-z")) { 8225117Ssklower zflag++, argc--, argv++; 8325117Ssklower goto again; 8425117Ssklower } 8525117Ssklower if (argc > 0 && !strcmp(*argv, "-s")) { 8625117Ssklower sflag++, argc--, argv++; 8725117Ssklower goto again; 8825117Ssklower } 8925117Ssklower if (argc > 0 && !strcmp(*argv, "-t")) { 9025117Ssklower tflag++, argc--, argv++; 9125117Ssklower goto again; 9225117Ssklower } 9325117Ssklower if (argc > 0 && !strcmp(*argv, "-j")) { 9425117Ssklower jflag++, argc--, argv++; 9525117Ssklower goto again; 9625117Ssklower } 9725117Ssklower if (argc > 0 && !strcmp(*argv, "-p")) { 9825117Ssklower argc--, argv++; 9925117Ssklower if (argc < 1) { 10025117Ssklower fprintf(stderr, "-p: missing sppcb address\n"); 10125117Ssklower exit(1); 10225117Ssklower } 10325117Ssklower if (npcbs >= SPP_NDEBUG) { 10425117Ssklower fprintf(stderr, "-p: too many pcb's specified\n"); 10525117Ssklower exit(1); 10625117Ssklower } 10725117Ssklower sscanf(*argv, "%x", &spp_pcbs[npcbs++]); 10825117Ssklower argc--, argv++; 10925117Ssklower goto again; 11025117Ssklower } 11125117Ssklower if (argc > 0) { 11225117Ssklower system = *argv; 11325117Ssklower argc--, argv++; 11425117Ssklower mask++; 115*52256Sbostic /* 116*52256Sbostic * Discard setgid privileges if not the running kernel so that 117*52256Sbostic * bad guys can't print interesting stuff from kernel memory. 118*52256Sbostic */ 119*52256Sbostic setgid(getgid()); 12025117Ssklower } 12125117Ssklower if (argc > 0) { 12225117Ssklower core = *argv; 12325117Ssklower argc--, argv++; 12425117Ssklower mask++; 125*52256Sbostic setgid(getgid()); 12625117Ssklower } 12725117Ssklower (void) nlist(system, nl); 12825117Ssklower if (nl[0].n_value == 0) { 12925117Ssklower fprintf(stderr, "trsp: %s: no namelist\n", system); 13025117Ssklower exit(1); 13125117Ssklower } 13225117Ssklower (void) close(0); 13325117Ssklower if (open(core, 0) < 0) { 13425117Ssklower fprintf(stderr, "trsp: "); perror(core); 13525117Ssklower exit(2); 13625117Ssklower } 13725117Ssklower if (mask) { 13825117Ssklower nl[0].n_value &= 0x7fffffff; 13925117Ssklower nl[1].n_value &= 0x7fffffff; 14025117Ssklower } 14125117Ssklower (void) lseek(0, nl[1].n_value, 0); 14225117Ssklower if (read(0, &spp_debx, sizeof (spp_debx)) != sizeof (spp_debx)) { 14325117Ssklower fprintf(stderr, "trsp: "); perror("spp_debx"); 14425117Ssklower exit(3); 14525117Ssklower } 14625117Ssklower printf("spp_debx=%d\n", spp_debx); 14725117Ssklower (void) lseek(0, nl[0].n_value, 0); 14825117Ssklower if (read(0, spp_debug, sizeof (spp_debug)) != sizeof (spp_debug)) { 14925117Ssklower fprintf(stderr, "trsp: "); perror("spp_debug"); 15025117Ssklower exit(3); 15125117Ssklower } 15225117Ssklower /* 15325117Ssklower * Here, we just want to clear out the old trace data and start over. 15425117Ssklower */ 15525117Ssklower if (zflag) { 15625117Ssklower char *cp = (char *) spp_debug, 15725117Ssklower *cplim = cp + sizeof(spp_debug); 15825117Ssklower (void) close(0); 15925117Ssklower if (open(core, 2) < 0) { 16025117Ssklower fprintf(stderr, "trsp: "); perror(core); 16125117Ssklower exit(2); 16225117Ssklower } 16325117Ssklower while(cp < cplim) *cp++ = 0; 16425117Ssklower (void) lseek(0, nl[0].n_value, 0); 16525117Ssklower if (write(0, spp_debug, sizeof (spp_debug)) != sizeof (spp_debug)) { 16625117Ssklower fprintf(stderr, "trsp: "); perror("spp_debug"); 16725117Ssklower exit(3); 16825117Ssklower } 16925117Ssklower (void) lseek(0, nl[1].n_value, 0); 17025117Ssklower spp_debx = 0; 17125117Ssklower if (write(0, &spp_debx, sizeof (spp_debx)) != sizeof (spp_debx)) { 17225117Ssklower fprintf(stderr, "trsp: "); perror("spp_debx"); 17325117Ssklower exit(3); 17425117Ssklower } 17525117Ssklower exit(0); 17625117Ssklower } 17725117Ssklower /* 17825117Ssklower * If no control blocks have been specified, figure 17925117Ssklower * out how many distinct one we have and summarize 18025117Ssklower * them in spp_pcbs for sorting the trace records 18125117Ssklower * below. 18225117Ssklower */ 18325117Ssklower if (npcbs == 0) { 18425117Ssklower for (i = 0; i < SPP_NDEBUG; i++) { 18525117Ssklower register int j; 18625117Ssklower register struct spp_debug *sd = &spp_debug[i]; 18725117Ssklower 18825117Ssklower if (sd->sd_cb == 0) 18925117Ssklower continue; 19025117Ssklower for (j = 0; j < npcbs; j++) 19125117Ssklower if (spp_pcbs[j] == sd->sd_cb) 19225117Ssklower break; 19325117Ssklower if (j >= npcbs) 19425117Ssklower spp_pcbs[npcbs++] = sd->sd_cb; 19525117Ssklower } 19625117Ssklower } 19725117Ssklower qsort(spp_pcbs, npcbs, sizeof (caddr_t), numeric); 19825117Ssklower if (jflag) { 19925117Ssklower char *cp = ""; 20025117Ssklower 20125117Ssklower for (i = 0; i < npcbs; i++) { 20225117Ssklower printf("%s%x", cp, spp_pcbs[i]); 20325117Ssklower cp = ", "; 20425117Ssklower } 20525117Ssklower if (*cp) 20625117Ssklower putchar('\n'); 20725117Ssklower exit(0); 20825117Ssklower } 20925117Ssklower for (i = 0; i < npcbs; i++) { 21025117Ssklower printf("\n%x:\n", spp_pcbs[i]); 21125117Ssklower dotrace(spp_pcbs[i]); 21225117Ssklower } 21325117Ssklower exit(0); 21425117Ssklower } 21525117Ssklower 21625117Ssklower dotrace(sppcb) 21725117Ssklower register caddr_t sppcb; 21825117Ssklower { 21925117Ssklower register int i; 22025117Ssklower register struct spp_debug *sd; 22125117Ssklower 22225117Ssklower for (i = spp_debx % SPP_NDEBUG; i < SPP_NDEBUG; i++) { 22325117Ssklower sd = &spp_debug[i]; 22425117Ssklower if (sppcb && sd->sd_cb != sppcb) 22525117Ssklower continue; 22625117Ssklower ntime = ntohl(sd->sd_time); 22725117Ssklower spp_trace(sd->sd_act, sd->sd_ostate, sd->sd_cb, &sd->sd_sp, 22825117Ssklower &sd->sd_si, sd->sd_req); 22925117Ssklower } 23025117Ssklower for (i = 0; i < spp_debx % SPP_NDEBUG; i++) { 23125117Ssklower sd = &spp_debug[i]; 23225117Ssklower if (sppcb && sd->sd_cb != sppcb) 23325117Ssklower continue; 23425117Ssklower ntime = ntohl(sd->sd_time); 23525117Ssklower spp_trace(sd->sd_act, sd->sd_ostate, sd->sd_cb, &sd->sd_sp, 23625117Ssklower &sd->sd_si, sd->sd_req); 23725117Ssklower } 23825117Ssklower } 23925117Ssklower 24025117Ssklower ptime(ms) 24125117Ssklower int ms; 24225117Ssklower { 24325117Ssklower 24425117Ssklower printf("%03d ", (ms/10) % 1000); 24525117Ssklower } 24625117Ssklower 24725117Ssklower numeric(c1, c2) 24825117Ssklower caddr_t *c1, *c2; 24925117Ssklower { 25025117Ssklower 25125117Ssklower return (*c1 - *c2); 25225117Ssklower } 25325117Ssklower 25425117Ssklower spp_trace(act, ostate, asp, sp, si, req) 25525117Ssklower short act, ostate; 25625117Ssklower struct sppcb *asp, *sp; 25725117Ssklower struct spidp *si; 25825117Ssklower int req; 25925117Ssklower { 26025117Ssklower u_short seq, ack, len, alo; 26125117Ssklower int flags, timer; 26225117Ssklower char *cp; 26325117Ssklower 26425117Ssklower if(ostate >= TCP_NSTATES) ostate = 0; 26525117Ssklower if(act > SA_DROP) act = SA_DROP; 26625117Ssklower printf("\n"); 26725117Ssklower ptime(ntime); 26825117Ssklower printf("%s:%s", tcpstates[ostate], sanames[act]); 26925117Ssklower 27025117Ssklower if (si != 0) { 27125117Ssklower seq = si->si_seq; 27225117Ssklower ack = si->si_ack; 27325117Ssklower alo = si->si_alo; 27425117Ssklower len = si->si_len; 27525117Ssklower switch (act) { 27625117Ssklower case SA_RESPOND: 27725117Ssklower case SA_OUTPUT: 27825117Ssklower seq = ntohs(seq); 27925117Ssklower ack = ntohs(ack); 28025117Ssklower alo = ntohs(alo); 28125117Ssklower len = ntohs(len); 28225117Ssklower case SA_INPUT: 28325117Ssklower case SA_DROP: 28425117Ssklower if (aflag) { 28525117Ssklower printf("\n\tsna="); 28625117Ssklower ns_printhost(&si->si_sna); 28725117Ssklower printf("\tdna="); 28825117Ssklower ns_printhost(&si->si_dna); 28925117Ssklower } 29025117Ssklower printf("\n\t"); 29146933Sbostic #define p1(name, f) { \ 29246933Sbostic printf("%s = %x, ", name, f); \ 29346933Sbostic } 29446933Sbostic p1("seq", seq); 29546933Sbostic p1("ack", ack); 29646933Sbostic p1("alo", alo); 29746933Sbostic p1("len", len); 29825117Ssklower flags = si->si_cc; 29925117Ssklower printf("flags=%x", flags); 30046933Sbostic #define pf(name, f) { \ 30146933Sbostic if (flags & f) { \ 30246933Sbostic printf("%s%s", cp, name); \ 30346933Sbostic cp = ","; \ 30446933Sbostic } \ 30546933Sbostic } 30625117Ssklower if (flags) { 30725117Ssklower char *cp = "<"; 30846933Sbostic pf("SP_SP", SP_SP); 30946933Sbostic pf("SP_SA", SP_SA); 31046933Sbostic pf("SP_OB", SP_OB); 31146933Sbostic pf("SP_EM", SP_EM); 31225117Ssklower printf(">"); 31325117Ssklower } 31425117Ssklower printf(", "); 31546933Sbostic #define p2(name, f) { \ 31646933Sbostic printf("%s = %x, ", name, f); \ 31746933Sbostic } 31846933Sbostic p2("sid", si->si_sid); 31946933Sbostic p2("did", si->si_did); 32046933Sbostic p2("dt", si->si_dt); 32125117Ssklower printf("\n\tsna="); 32225117Ssklower ns_printhost(&si->si_sna); 32325117Ssklower printf("\tdna="); 32425117Ssklower ns_printhost(&si->si_dna); 32525117Ssklower } 32625117Ssklower } 32725117Ssklower if(act == SA_USER) { 32825117Ssklower printf("\treq=%s", prurequests[req&0xff]); 32925117Ssklower if ((req & 0xff) == PRU_SLOWTIMO) 33025117Ssklower printf("<%s>", tcptimers[req>>8]); 33125117Ssklower } 33225117Ssklower printf(" -> %s", tcpstates[sp->s_state]); 33325117Ssklower 33425117Ssklower /* print out internal state of sp !?! */ 33525117Ssklower printf("\n"); 33625117Ssklower if (sp == 0) 33725117Ssklower return; 33846933Sbostic #define p3(name, f) { \ 33946933Sbostic printf("%s = %x, ", name, f); \ 34046933Sbostic } 34146933Sbostic if (sflag) { 34246933Sbostic printf("\t"); 34346933Sbostic p3("rack", sp->s_rack); 34446933Sbostic p3("ralo", sp->s_ralo); 34546933Sbostic p3("smax", sp->s_smax); 34646933Sbostic p3("snxt", sp->s_snxt); 34746933Sbostic p3("flags", sp->s_flags); 34825117Ssklower #undef pf 34946933Sbostic #define pf(name, f) { \ 35046933Sbostic if (flags & f) { \ 35146933Sbostic printf("%s%s", cp, name); \ 35246933Sbostic cp = ","; \ 35346933Sbostic } \ 35446933Sbostic } 35525117Ssklower flags = sp->s_flags; 35625117Ssklower if (flags || sp->s_oobflags) { 35725117Ssklower char *cp = "<"; 35846933Sbostic pf("ACKNOW", SF_ACKNOW); 35946933Sbostic pf("DELACK", SF_DELACK); 36046933Sbostic pf("HI", SF_HI); 36146933Sbostic pf("HO", SF_HO); 36246933Sbostic pf("PI", SF_PI); 36346933Sbostic pf("WIN", SF_WIN); 36446933Sbostic pf("RXT", SF_RXT); 36546933Sbostic pf("RVD", SF_RVD); 36625117Ssklower flags = sp->s_oobflags; 36746933Sbostic pf("SOOB", SF_SOOB); 36846933Sbostic pf("IOOB", SF_IOOB); 36925117Ssklower printf(">"); 37025117Ssklower } 37125117Ssklower } 37225117Ssklower /* print out timers? */ 37325117Ssklower if (tflag) { 37425117Ssklower char *cp = "\t"; 37525117Ssklower register int i; 37625117Ssklower 37725117Ssklower printf("\n\tTIMERS: "); 37846933Sbostic p3("idle", sp->s_idle); 37946933Sbostic p3("force", sp->s_force); 38046933Sbostic p3("rtseq", sp->s_rtseq); 38125117Ssklower for (i = 0; i < TCPT_NTIMERS; i++) { 38225117Ssklower if (sp->s_timer[i] == 0) 38325117Ssklower continue; 38425117Ssklower printf("%s%s=%d", cp, tcptimers[i], sp->s_timer[i]); 38525117Ssklower if (i == TCPT_REXMT) 38625117Ssklower printf(" (s_rxtshft=%d)", sp->s_rxtshift); 38725117Ssklower cp = ", "; 38825117Ssklower } 38925117Ssklower if (*cp != '\t') 39025117Ssklower putchar('\n'); 39125117Ssklower } 39225117Ssklower } 39325117Ssklower 39425117Ssklower ns_printhost(p) 39525117Ssklower register struct ns_addr *p; 39625117Ssklower { 39725117Ssklower 39825117Ssklower printf("<net:%x%x,host:%4.4x%4.4x%4.4x,port:%x>", 39925117Ssklower p->x_net.s_net[0], 40025117Ssklower p->x_net.s_net[1], 40125117Ssklower p->x_host.s_host[0], 40225117Ssklower p->x_host.s_host[1], 40325117Ssklower p->x_host.s_host[2], 40425117Ssklower p->x_port); 40525117Ssklower 40625117Ssklower } 40725117Ssklower 408