16463Swnj #ifndef lint 2*10593Ssam static char sccsid[] = "@(#)trpt.c 4.7 01/22/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; 38*10593Ssam 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; 48*10593Ssam 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: 59*10593Ssam if (argc > 0 && !strcmp(*argv, "-a")) { 60*10593Ssam aflag++, argc--, argv++; 61*10593Ssam goto again; 62*10593Ssam } 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: 206*10593Ssam if (aflag) { 207*10593Ssam printf("(src=%s,%d, ", ntoa(ti->ti_src), 208*10593Ssam ntohs(ti->ti_sport)); 209*10593Ssam printf("dst=%s,%d)", ntoa(ti->ti_dst), 210*10593Ssam ntohs(ti->ti_dport)); 211*10593Ssam } 2126463Swnj seq = ti->ti_seq; 2136463Swnj ack = ti->ti_ack; 2146463Swnj len = ti->ti_len; 2156463Swnj win = ti->ti_win; 2166463Swnj if (act == TA_OUTPUT) { 2176463Swnj seq = ntohl(seq); 2186463Swnj ack = ntohl(ack); 2196463Swnj len = ntohs(len); 2206463Swnj win = ntohs(win); 2216463Swnj } 2226463Swnj if (act == TA_OUTPUT) 2236463Swnj len -= sizeof (struct tcphdr); 2246463Swnj if (len) 2256463Swnj printf("[%x..%x)", seq, seq+len); 2266463Swnj else 2276463Swnj printf("%x", seq); 2286463Swnj printf("@%x", ack); 2296463Swnj if (win) 2306463Swnj printf("(win=%d)", win); 2316463Swnj flags = ti->ti_flags; 2326463Swnj if (flags) { 2336463Swnj char *cp = "<"; 2346463Swnj #define pf(f) { if (ti->ti_flags&TH_/**/f) { printf("%s%s", cp, "f"); cp = ","; } } 23510411Ssam pf(SYN); pf(ACK); pf(FIN); pf(RST); pf(PUSH); pf(URG); 2366463Swnj printf(">"); 2376463Swnj } 2386463Swnj break; 2396463Swnj 2406463Swnj case TA_USER: 2418382Ssam timer = req >> 8; 2428382Ssam req &= 0xff; 2438382Ssam printf("%s", prurequests[req]); 2448382Ssam if (req == PRU_SLOWTIMO || req == PRU_FASTTIMO) 2458382Ssam printf("<%s>", tcptimers[timer]); 2466463Swnj break; 2476463Swnj } 2486463Swnj printf(" -> %s", tcpstates[tp->t_state]); 2496463Swnj /* print out internal state of tp !?! */ 2506463Swnj printf("\n"); 2516463Swnj if (sflag) { 2526463Swnj printf("\trcv_nxt %x rcv_wnd %d snd_una %x snd_nxt %x snd_max %x\n", 25310272Ssam tp->rcv_nxt, tp->rcv_wnd, tp->snd_una, tp->snd_nxt, 25410272Ssam tp->snd_max); 25510272Ssam printf("\tsnd_wl1 %x snd_wl2 %x snd_wnd %x\n", tp->snd_wl1, 25610272Ssam tp->snd_wl2, tp->snd_wnd); 2576463Swnj } 25810425Ssam /* print out timers? */ 25910425Ssam if (tflag) { 26010425Ssam char *cp = "\t"; 26110425Ssam register int i; 26210425Ssam 26310425Ssam for (i = 0; i < TCPT_NTIMERS; i++) { 26410425Ssam if (tp->t_timer[i] == 0) 26510425Ssam continue; 26610425Ssam printf("%s%s=%d", cp, tcptimers[i], tp->t_timer[i]); 26710425Ssam if (i == TCPT_REXMT) 26810425Ssam printf(" (t_rxtshft=%d)", tp->t_rxtshift); 26910425Ssam cp = ", "; 27010425Ssam } 27110425Ssam if (*cp != '\t') 27210425Ssam putchar('\n'); 27310425Ssam } 2746463Swnj } 2756463Swnj 2766463Swnj ptime(ms) 2776463Swnj int ms; 2786463Swnj { 2796463Swnj 2806463Swnj printf("%03d ", (ms/10) % 1000); 2816463Swnj } 28210425Ssam 28310425Ssam numeric(c1, c2) 28410425Ssam caddr_t *c1, *c2; 28510425Ssam { 28610425Ssam 28710425Ssam return (*c1 - *c2); 28810425Ssam } 289*10593Ssam 290*10593Ssam /* 291*10593Ssam * Convert network-format internet address 292*10593Ssam * to base 256 d.d.d.d representation. 293*10593Ssam */ 294*10593Ssam char * 295*10593Ssam ntoa(in) 296*10593Ssam struct in_addr in; 297*10593Ssam { 298*10593Ssam static char b[18]; 299*10593Ssam register char *p; 300*10593Ssam 301*10593Ssam in.s_addr = ntohl(in.s_addr); 302*10593Ssam p = (char *)∈ 303*10593Ssam #define UC(b) (((int)b)&0xff) 304*10593Ssam sprintf(b, "%d.%d.%d.%d", UC(p[0]), UC(p[1]), UC(p[2]), UC(p[3])); 305*10593Ssam return (b); 306*10593Ssam } 307