16463Swnj #ifndef lint 2*14282Shelge static char sccsid[] = "@(#)trpt.c 4.10 07/29/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; 3610425Ssam int tflag; 3710425Ssam int jflag; 3810593Ssam int aflag; 3910425Ssam int numeric(); 406463Swnj struct nlist nl[] = { 416463Swnj { "_tcp_debug" }, 426463Swnj { "_tcp_debx" }, 436463Swnj 0 446463Swnj }; 456463Swnj struct tcp_debug tcp_debug[TCP_NDEBUG]; 4610425Ssam caddr_t tcp_pcbs[TCP_NDEBUG]; 476463Swnj int tcp_debx; 4810593Ssam char *ntoa(); 496463Swnj 506463Swnj main(argc, argv) 516463Swnj int argc; 526463Swnj char **argv; 536463Swnj { 5410425Ssam int i, mask = 0, npcbs = 0; 5510272Ssam char *system = "/vmunix", *core = "/dev/kmem"; 566463Swnj 576463Swnj argc--, argv++; 586463Swnj again: 5910593Ssam if (argc > 0 && !strcmp(*argv, "-a")) { 6010593Ssam aflag++, argc--, argv++; 6110593Ssam goto again; 6210593Ssam } 636463Swnj if (argc > 0 && !strcmp(*argv, "-s")) { 646463Swnj sflag++, argc--, argv++; 656463Swnj goto again; 666463Swnj } 6710425Ssam if (argc > 0 && !strcmp(*argv, "-t")) { 6810425Ssam tflag++, argc--, argv++; 6910425Ssam goto again; 7010425Ssam } 7110425Ssam if (argc > 0 && !strcmp(*argv, "-j")) { 7210425Ssam jflag++, argc--, argv++; 7310425Ssam goto again; 7410425Ssam } 7510272Ssam if (argc > 0 && !strcmp(*argv, "-p")) { 7610425Ssam argc--, argv++; 7710272Ssam if (argc < 1) { 7810272Ssam fprintf(stderr, "-p: missing tcpcb address\n"); 7910272Ssam exit(1); 8010272Ssam } 8110425Ssam if (npcbs >= TCP_NDEBUG) { 8210425Ssam fprintf(stderr, "-p: too many pcb's specified\n"); 8310425Ssam exit(1); 8410425Ssam } 8510425Ssam sscanf(*argv, "%x", &tcp_pcbs[npcbs++]); 8610272Ssam argc--, argv++; 8710272Ssam goto again; 8810272Ssam } 8910272Ssam if (argc > 0) { 9010272Ssam system = *argv; 9110272Ssam argc--, argv++; 9210272Ssam mask++; 9310272Ssam } 9410272Ssam if (argc > 0) { 9510272Ssam core = *argv; 9610272Ssam argc--, argv++; 9710272Ssam mask++; 9810272Ssam } 9910272Ssam (void) nlist(system, nl); 1006463Swnj if (nl[0].n_value == 0) { 10110272Ssam fprintf(stderr, "trpt: %s: no namelist\n", system); 1026463Swnj exit(1); 1036463Swnj } 10410272Ssam (void) close(0); 10510272Ssam if (open(core, 0) < 0) { 10610272Ssam fprintf(stderr, "trpt: "); perror(core); 10710272Ssam exit(2); 10810272Ssam } 10910272Ssam if (mask) { 1106463Swnj nl[0].n_value &= 0x7fffffff; 1116463Swnj nl[1].n_value &= 0x7fffffff; 1126463Swnj } 11310272Ssam (void) lseek(0, nl[1].n_value, 0); 11410272Ssam if (read(0, &tcp_debx, sizeof (tcp_debx)) != sizeof (tcp_debx)) { 11510272Ssam fprintf(stderr, "trpt: "); perror("tcp_debx"); 11610272Ssam exit(3); 11710272Ssam } 1186463Swnj printf("tcp_debx=%d\n", tcp_debx); 11910272Ssam (void) lseek(0, nl[0].n_value, 0); 12010272Ssam if (read(0, tcp_debug, sizeof (tcp_debug)) != sizeof (tcp_debug)) { 12110272Ssam fprintf(stderr, "trpt: "); perror("tcp_debug"); 12210272Ssam exit(3); 12310272Ssam } 12410425Ssam /* 12510425Ssam * If no control blocks have been specified, figure 12610425Ssam * out how many distinct one we have and summarize 12710425Ssam * them in tcp_pcbs for sorting the trace records 12810425Ssam * below. 12910425Ssam */ 13010425Ssam if (npcbs == 0) { 13110425Ssam for (i = 0; i < TCP_NDEBUG; i++) { 13210425Ssam register int j; 13310425Ssam register struct tcp_debug *td = &tcp_debug[i]; 1348382Ssam 13510425Ssam if (td->td_tcb == 0) 13610425Ssam continue; 13710425Ssam for (j = 0; j < npcbs; j++) 13810425Ssam if (tcp_pcbs[j] == td->td_tcb) 13910425Ssam break; 14010425Ssam if (j >= npcbs) 14110425Ssam tcp_pcbs[npcbs++] = td->td_tcb; 14210425Ssam } 14310425Ssam } 14410425Ssam qsort(tcp_pcbs, npcbs, sizeof (caddr_t), numeric); 14510425Ssam if (jflag) { 14610425Ssam char *cp = ""; 14710425Ssam 14810425Ssam for (i = 0; i < npcbs; i++) { 14910425Ssam printf("%s%x", cp, tcp_pcbs[i]); 15010425Ssam cp = ", "; 15110425Ssam } 15210425Ssam if (*cp) 15310425Ssam putchar('\n'); 15410425Ssam exit(0); 15510425Ssam } 15610425Ssam for (i = 0; i < npcbs; i++) { 15710425Ssam printf("\n%x:\n", tcp_pcbs[i]); 15810425Ssam dotrace(tcp_pcbs[i]); 15910425Ssam } 16010425Ssam exit(0); 16110425Ssam } 16210425Ssam 16310425Ssam dotrace(tcpcb) 16410425Ssam register caddr_t tcpcb; 16510425Ssam { 16610425Ssam register int i; 16710425Ssam register struct tcp_debug *td; 16810425Ssam 16910425Ssam for (i = 0; i < tcp_debx % TCP_NDEBUG; i++) { 17010425Ssam td = &tcp_debug[i]; 17110272Ssam if (tcpcb && td->td_tcb != tcpcb) 17210272Ssam continue; 1738382Ssam ntime = ntohl(td->td_time); 1746463Swnj tcp_trace(td->td_act, td->td_ostate, td->td_tcb, &td->td_cb, 1756463Swnj &td->td_ti, td->td_req); 1766463Swnj } 17710425Ssam for (i = tcp_debx % TCP_NDEBUG; i < TCP_NDEBUG; i++) { 17810425Ssam td = &tcp_debug[i]; 17910272Ssam if (tcpcb && td->td_tcb != tcpcb) 18010272Ssam continue; 1818382Ssam ntime = ntohl(td->td_time); 1826463Swnj tcp_trace(td->td_act, td->td_ostate, td->td_tcb, &td->td_cb, 1836463Swnj &td->td_ti, td->td_req); 1846463Swnj } 1856463Swnj } 1866463Swnj 1876463Swnj /* 1886463Swnj * Tcp debug routines 1896463Swnj */ 1906463Swnj tcp_trace(act, ostate, atp, tp, ti, req) 1916463Swnj short act, ostate; 1926463Swnj struct tcpcb *atp, *tp; 1936463Swnj struct tcpiphdr *ti; 1946463Swnj int req; 1956463Swnj { 1966463Swnj tcp_seq seq, ack; 1978382Ssam int len, flags, win, timer; 1986463Swnj char *cp; 1996463Swnj 2006463Swnj ptime(ntime); 20110425Ssam printf("%s:%s ", tcpstates[ostate], tanames[act]); 2026463Swnj switch (act) { 2036463Swnj 2046463Swnj case TA_INPUT: 2056463Swnj case TA_OUTPUT: 20614004Shelge case TA_DROP: 20710593Ssam if (aflag) { 20810593Ssam printf("(src=%s,%d, ", ntoa(ti->ti_src), 20910593Ssam ntohs(ti->ti_sport)); 21010593Ssam printf("dst=%s,%d)", ntoa(ti->ti_dst), 21110593Ssam ntohs(ti->ti_dport)); 21210593Ssam } 2136463Swnj seq = ti->ti_seq; 2146463Swnj ack = ti->ti_ack; 2156463Swnj len = ti->ti_len; 2166463Swnj win = ti->ti_win; 2176463Swnj if (act == TA_OUTPUT) { 2186463Swnj seq = ntohl(seq); 2196463Swnj ack = ntohl(ack); 2206463Swnj len = ntohs(len); 2216463Swnj win = ntohs(win); 2226463Swnj } 2236463Swnj if (act == TA_OUTPUT) 2246463Swnj len -= sizeof (struct tcphdr); 2256463Swnj if (len) 2266463Swnj printf("[%x..%x)", seq, seq+len); 2276463Swnj else 2286463Swnj printf("%x", seq); 2296463Swnj printf("@%x", ack); 2306463Swnj if (win) 231*14282Shelge printf("(win=%x)", win); 2326463Swnj flags = ti->ti_flags; 2336463Swnj if (flags) { 2346463Swnj char *cp = "<"; 2356463Swnj #define pf(f) { if (ti->ti_flags&TH_/**/f) { printf("%s%s", cp, "f"); cp = ","; } } 23610411Ssam pf(SYN); pf(ACK); pf(FIN); pf(RST); pf(PUSH); pf(URG); 2376463Swnj printf(">"); 2386463Swnj } 2396463Swnj break; 2406463Swnj 2416463Swnj case TA_USER: 2428382Ssam timer = req >> 8; 2438382Ssam req &= 0xff; 2448382Ssam printf("%s", prurequests[req]); 2458382Ssam if (req == PRU_SLOWTIMO || req == PRU_FASTTIMO) 2468382Ssam printf("<%s>", tcptimers[timer]); 2476463Swnj break; 2486463Swnj } 2496463Swnj printf(" -> %s", tcpstates[tp->t_state]); 2506463Swnj /* print out internal state of tp !?! */ 2516463Swnj printf("\n"); 2526463Swnj if (sflag) { 25314000Shelge printf("\trcv_nxt %x rcv_wnd %x snd_una %x snd_nxt %x snd_max %x\n", 25410272Ssam tp->rcv_nxt, tp->rcv_wnd, tp->snd_una, tp->snd_nxt, 25510272Ssam tp->snd_max); 25610272Ssam printf("\tsnd_wl1 %x snd_wl2 %x snd_wnd %x\n", tp->snd_wl1, 25710272Ssam tp->snd_wl2, tp->snd_wnd); 2586463Swnj } 25910425Ssam /* print out timers? */ 26010425Ssam if (tflag) { 26110425Ssam char *cp = "\t"; 26210425Ssam register int i; 26310425Ssam 26410425Ssam for (i = 0; i < TCPT_NTIMERS; i++) { 26510425Ssam if (tp->t_timer[i] == 0) 26610425Ssam continue; 26710425Ssam printf("%s%s=%d", cp, tcptimers[i], tp->t_timer[i]); 26810425Ssam if (i == TCPT_REXMT) 26910425Ssam printf(" (t_rxtshft=%d)", tp->t_rxtshift); 27010425Ssam cp = ", "; 27110425Ssam } 27210425Ssam if (*cp != '\t') 27310425Ssam putchar('\n'); 27410425Ssam } 2756463Swnj } 2766463Swnj 2776463Swnj ptime(ms) 2786463Swnj int ms; 2796463Swnj { 2806463Swnj 2816463Swnj printf("%03d ", (ms/10) % 1000); 2826463Swnj } 28310425Ssam 28410425Ssam numeric(c1, c2) 28510425Ssam caddr_t *c1, *c2; 28610425Ssam { 28710425Ssam 28810425Ssam return (*c1 - *c2); 28910425Ssam } 29010593Ssam 29110593Ssam /* 29210593Ssam * Convert network-format internet address 29310593Ssam * to base 256 d.d.d.d representation. 29410593Ssam */ 29510593Ssam char * 29610593Ssam ntoa(in) 29710593Ssam struct in_addr in; 29810593Ssam { 29910593Ssam static char b[18]; 30010593Ssam register char *p; 30110593Ssam 30210593Ssam in.s_addr = ntohl(in.s_addr); 30310593Ssam p = (char *)∈ 30410593Ssam #define UC(b) (((int)b)&0xff) 30510593Ssam sprintf(b, "%d.%d.%d.%d", UC(p[0]), UC(p[1]), UC(p[2]), UC(p[3])); 30610593Ssam return (b); 30710593Ssam } 308