16463Swnj #ifndef lint 2*10425Ssam static char sccsid[] = "@(#)trpt.c 4.6 01/19/83"; 36463Swnj #endif 46463Swnj 56463Swnj #include <sys/param.h> 66463Swnj #include <sys/socket.h> 76463Swnj #include <sys/socketvar.h> 86463Swnj #define PRUREQUESTS 96463Swnj #include <sys/protosw.h> 109202Ssam 116463Swnj #include <net/route.h> 126463Swnj #include <net/if.h> 139202Ssam 149202Ssam #include <netinet/in.h> 159202Ssam #include <netinet/in_pcb.h> 169202Ssam #include <netinet/in_systm.h> 179202Ssam #include <netinet/ip.h> 189202Ssam #include <netinet/ip_var.h> 199202Ssam #include <netinet/tcp.h> 206463Swnj #define TCPSTATES 219202Ssam #include <netinet/tcp_fsm.h> 229202Ssam #include <netinet/tcp_seq.h> 236463Swnj #define TCPTIMERS 249202Ssam #include <netinet/tcp_timer.h> 259202Ssam #include <netinet/tcp_var.h> 269202Ssam #include <netinet/tcpip.h> 276463Swnj #define TANAMES 289202Ssam #include <netinet/tcp_debug.h> 299202Ssam 3010272Ssam #include <stdio.h> 316463Swnj #include <errno.h> 326463Swnj #include <nlist.h> 336463Swnj 346463Swnj n_time ntime; 356463Swnj int sflag; 36*10425Ssam int tflag; 37*10425Ssam int jflag; 38*10425Ssam int numeric(); 396463Swnj struct nlist nl[] = { 406463Swnj { "_tcp_debug" }, 416463Swnj { "_tcp_debx" }, 426463Swnj 0 436463Swnj }; 446463Swnj struct tcp_debug tcp_debug[TCP_NDEBUG]; 45*10425Ssam caddr_t tcp_pcbs[TCP_NDEBUG]; 466463Swnj int tcp_debx; 476463Swnj 486463Swnj main(argc, argv) 496463Swnj int argc; 506463Swnj char **argv; 516463Swnj { 52*10425Ssam int i, mask = 0, npcbs = 0; 5310272Ssam char *system = "/vmunix", *core = "/dev/kmem"; 546463Swnj 556463Swnj argc--, argv++; 566463Swnj again: 576463Swnj if (argc > 0 && !strcmp(*argv, "-s")) { 586463Swnj sflag++, argc--, argv++; 596463Swnj goto again; 606463Swnj } 61*10425Ssam if (argc > 0 && !strcmp(*argv, "-t")) { 62*10425Ssam tflag++, argc--, argv++; 63*10425Ssam goto again; 64*10425Ssam } 65*10425Ssam if (argc > 0 && !strcmp(*argv, "-j")) { 66*10425Ssam jflag++, argc--, argv++; 67*10425Ssam goto again; 68*10425Ssam } 6910272Ssam if (argc > 0 && !strcmp(*argv, "-p")) { 70*10425Ssam argc--, argv++; 7110272Ssam if (argc < 1) { 7210272Ssam fprintf(stderr, "-p: missing tcpcb address\n"); 7310272Ssam exit(1); 7410272Ssam } 75*10425Ssam if (npcbs >= TCP_NDEBUG) { 76*10425Ssam fprintf(stderr, "-p: too many pcb's specified\n"); 77*10425Ssam exit(1); 78*10425Ssam } 79*10425Ssam sscanf(*argv, "%x", &tcp_pcbs[npcbs++]); 8010272Ssam argc--, argv++; 8110272Ssam goto again; 8210272Ssam } 8310272Ssam if (argc > 0) { 8410272Ssam system = *argv; 8510272Ssam argc--, argv++; 8610272Ssam mask++; 8710272Ssam } 8810272Ssam if (argc > 0) { 8910272Ssam core = *argv; 9010272Ssam argc--, argv++; 9110272Ssam mask++; 9210272Ssam } 9310272Ssam (void) nlist(system, nl); 946463Swnj if (nl[0].n_value == 0) { 9510272Ssam fprintf(stderr, "trpt: %s: no namelist\n", system); 966463Swnj exit(1); 976463Swnj } 9810272Ssam (void) close(0); 9910272Ssam if (open(core, 0) < 0) { 10010272Ssam fprintf(stderr, "trpt: "); perror(core); 10110272Ssam exit(2); 10210272Ssam } 10310272Ssam if (mask) { 1046463Swnj nl[0].n_value &= 0x7fffffff; 1056463Swnj nl[1].n_value &= 0x7fffffff; 1066463Swnj } 10710272Ssam (void) lseek(0, nl[1].n_value, 0); 10810272Ssam if (read(0, &tcp_debx, sizeof (tcp_debx)) != sizeof (tcp_debx)) { 10910272Ssam fprintf(stderr, "trpt: "); perror("tcp_debx"); 11010272Ssam exit(3); 11110272Ssam } 1126463Swnj printf("tcp_debx=%d\n", tcp_debx); 11310272Ssam (void) lseek(0, nl[0].n_value, 0); 11410272Ssam if (read(0, tcp_debug, sizeof (tcp_debug)) != sizeof (tcp_debug)) { 11510272Ssam fprintf(stderr, "trpt: "); perror("tcp_debug"); 11610272Ssam exit(3); 11710272Ssam } 118*10425Ssam /* 119*10425Ssam * If no control blocks have been specified, figure 120*10425Ssam * out how many distinct one we have and summarize 121*10425Ssam * them in tcp_pcbs for sorting the trace records 122*10425Ssam * below. 123*10425Ssam */ 124*10425Ssam if (npcbs == 0) { 125*10425Ssam for (i = 0; i < TCP_NDEBUG; i++) { 126*10425Ssam register int j; 127*10425Ssam register struct tcp_debug *td = &tcp_debug[i]; 1288382Ssam 129*10425Ssam if (td->td_tcb == 0) 130*10425Ssam continue; 131*10425Ssam for (j = 0; j < npcbs; j++) 132*10425Ssam if (tcp_pcbs[j] == td->td_tcb) 133*10425Ssam break; 134*10425Ssam if (j >= npcbs) 135*10425Ssam tcp_pcbs[npcbs++] = td->td_tcb; 136*10425Ssam } 137*10425Ssam } 138*10425Ssam qsort(tcp_pcbs, npcbs, sizeof (caddr_t), numeric); 139*10425Ssam if (jflag) { 140*10425Ssam char *cp = ""; 141*10425Ssam 142*10425Ssam for (i = 0; i < npcbs; i++) { 143*10425Ssam printf("%s%x", cp, tcp_pcbs[i]); 144*10425Ssam cp = ", "; 145*10425Ssam } 146*10425Ssam if (*cp) 147*10425Ssam putchar('\n'); 148*10425Ssam exit(0); 149*10425Ssam } 150*10425Ssam for (i = 0; i < npcbs; i++) { 151*10425Ssam printf("\n%x:\n", tcp_pcbs[i]); 152*10425Ssam dotrace(tcp_pcbs[i]); 153*10425Ssam } 154*10425Ssam exit(0); 155*10425Ssam } 156*10425Ssam 157*10425Ssam dotrace(tcpcb) 158*10425Ssam register caddr_t tcpcb; 159*10425Ssam { 160*10425Ssam register int i; 161*10425Ssam register struct tcp_debug *td; 162*10425Ssam 163*10425Ssam for (i = 0; i < tcp_debx % TCP_NDEBUG; i++) { 164*10425Ssam td = &tcp_debug[i]; 16510272Ssam if (tcpcb && td->td_tcb != tcpcb) 16610272Ssam continue; 1678382Ssam ntime = ntohl(td->td_time); 1686463Swnj tcp_trace(td->td_act, td->td_ostate, td->td_tcb, &td->td_cb, 1696463Swnj &td->td_ti, td->td_req); 1706463Swnj } 171*10425Ssam for (i = tcp_debx % TCP_NDEBUG; i < TCP_NDEBUG; i++) { 172*10425Ssam td = &tcp_debug[i]; 17310272Ssam if (tcpcb && td->td_tcb != tcpcb) 17410272Ssam continue; 1758382Ssam ntime = ntohl(td->td_time); 1766463Swnj tcp_trace(td->td_act, td->td_ostate, td->td_tcb, &td->td_cb, 1776463Swnj &td->td_ti, td->td_req); 1786463Swnj } 1796463Swnj } 1806463Swnj 1816463Swnj /* 1826463Swnj * Tcp debug routines 1836463Swnj */ 1846463Swnj tcp_trace(act, ostate, atp, tp, ti, req) 1856463Swnj short act, ostate; 1866463Swnj struct tcpcb *atp, *tp; 1876463Swnj struct tcpiphdr *ti; 1886463Swnj int req; 1896463Swnj { 1906463Swnj tcp_seq seq, ack; 1918382Ssam int len, flags, win, timer; 1926463Swnj char *cp; 1936463Swnj 1946463Swnj ptime(ntime); 195*10425Ssam printf("%s:%s ", tcpstates[ostate], tanames[act]); 1966463Swnj switch (act) { 1976463Swnj 1986463Swnj case TA_INPUT: 1996463Swnj case TA_OUTPUT: 2006463Swnj seq = ti->ti_seq; 2016463Swnj ack = ti->ti_ack; 2026463Swnj len = ti->ti_len; 2036463Swnj win = ti->ti_win; 2046463Swnj if (act == TA_OUTPUT) { 2056463Swnj seq = ntohl(seq); 2066463Swnj ack = ntohl(ack); 2076463Swnj len = ntohs(len); 2086463Swnj win = ntohs(win); 2096463Swnj } 2106463Swnj if (act == TA_OUTPUT) 2116463Swnj len -= sizeof (struct tcphdr); 2126463Swnj if (len) 2136463Swnj printf("[%x..%x)", seq, seq+len); 2146463Swnj else 2156463Swnj printf("%x", seq); 2166463Swnj printf("@%x", ack); 2176463Swnj if (win) 2186463Swnj printf("(win=%d)", win); 2196463Swnj flags = ti->ti_flags; 2206463Swnj if (flags) { 2216463Swnj char *cp = "<"; 2226463Swnj #define pf(f) { if (ti->ti_flags&TH_/**/f) { printf("%s%s", cp, "f"); cp = ","; } } 22310411Ssam pf(SYN); pf(ACK); pf(FIN); pf(RST); pf(PUSH); pf(URG); 2246463Swnj printf(">"); 2256463Swnj } 2266463Swnj break; 2276463Swnj 2286463Swnj case TA_USER: 2298382Ssam timer = req >> 8; 2308382Ssam req &= 0xff; 2318382Ssam printf("%s", prurequests[req]); 2328382Ssam if (req == PRU_SLOWTIMO || req == PRU_FASTTIMO) 2338382Ssam printf("<%s>", tcptimers[timer]); 2346463Swnj break; 2356463Swnj } 2366463Swnj printf(" -> %s", tcpstates[tp->t_state]); 2376463Swnj /* print out internal state of tp !?! */ 2386463Swnj printf("\n"); 2396463Swnj if (sflag) { 2406463Swnj printf("\trcv_nxt %x rcv_wnd %d snd_una %x snd_nxt %x snd_max %x\n", 24110272Ssam tp->rcv_nxt, tp->rcv_wnd, tp->snd_una, tp->snd_nxt, 24210272Ssam tp->snd_max); 24310272Ssam printf("\tsnd_wl1 %x snd_wl2 %x snd_wnd %x\n", tp->snd_wl1, 24410272Ssam tp->snd_wl2, tp->snd_wnd); 2456463Swnj } 246*10425Ssam /* print out timers? */ 247*10425Ssam if (tflag) { 248*10425Ssam char *cp = "\t"; 249*10425Ssam register int i; 250*10425Ssam 251*10425Ssam for (i = 0; i < TCPT_NTIMERS; i++) { 252*10425Ssam if (tp->t_timer[i] == 0) 253*10425Ssam continue; 254*10425Ssam printf("%s%s=%d", cp, tcptimers[i], tp->t_timer[i]); 255*10425Ssam if (i == TCPT_REXMT) 256*10425Ssam printf(" (t_rxtshft=%d)", tp->t_rxtshift); 257*10425Ssam cp = ", "; 258*10425Ssam } 259*10425Ssam if (*cp != '\t') 260*10425Ssam putchar('\n'); 261*10425Ssam } 2626463Swnj } 2636463Swnj 2646463Swnj ptime(ms) 2656463Swnj int ms; 2666463Swnj { 2676463Swnj 2686463Swnj printf("%03d ", (ms/10) % 1000); 2696463Swnj } 270*10425Ssam 271*10425Ssam numeric(c1, c2) 272*10425Ssam caddr_t *c1, *c2; 273*10425Ssam { 274*10425Ssam 275*10425Ssam return (*c1 - *c2); 276*10425Ssam } 277