1 #ifndef lint 2 static char sccsid[] = "@(#)trpt.c 4.12 06/03/85"; 3 #endif 4 5 #include <sys/param.h> 6 #include <sys/socket.h> 7 #include <sys/socketvar.h> 8 #define PRUREQUESTS 9 #include <sys/protosw.h> 10 11 #include <net/route.h> 12 #include <net/if.h> 13 14 #include <netinet/in.h> 15 #include <netinet/in_pcb.h> 16 #include <netinet/in_systm.h> 17 #include <netinet/ip.h> 18 #include <netinet/ip_var.h> 19 #include <netinet/tcp.h> 20 #define TCPSTATES 21 #include <netinet/tcp_fsm.h> 22 #include <netinet/tcp_seq.h> 23 #define TCPTIMERS 24 #include <netinet/tcp_timer.h> 25 #include <netinet/tcp_var.h> 26 #include <netinet/tcpip.h> 27 #define TANAMES 28 #include <netinet/tcp_debug.h> 29 30 #include <arpa/inet.h> 31 32 #include <stdio.h> 33 #include <errno.h> 34 #include <nlist.h> 35 36 n_time ntime; 37 int sflag; 38 int tflag; 39 int jflag; 40 int aflag; 41 int numeric(); 42 struct nlist nl[] = { 43 { "_tcp_debug" }, 44 { "_tcp_debx" }, 45 0 46 }; 47 struct tcp_debug tcp_debug[TCP_NDEBUG]; 48 caddr_t tcp_pcbs[TCP_NDEBUG]; 49 int tcp_debx; 50 51 main(argc, argv) 52 int argc; 53 char **argv; 54 { 55 int i, mask = 0, npcbs = 0; 56 char *system = "/vmunix", *core = "/dev/kmem"; 57 58 argc--, argv++; 59 again: 60 if (argc > 0 && !strcmp(*argv, "-a")) { 61 aflag++, argc--, argv++; 62 goto again; 63 } 64 if (argc > 0 && !strcmp(*argv, "-s")) { 65 sflag++, argc--, argv++; 66 goto again; 67 } 68 if (argc > 0 && !strcmp(*argv, "-t")) { 69 tflag++, argc--, argv++; 70 goto again; 71 } 72 if (argc > 0 && !strcmp(*argv, "-j")) { 73 jflag++, argc--, argv++; 74 goto again; 75 } 76 if (argc > 0 && !strcmp(*argv, "-p")) { 77 argc--, argv++; 78 if (argc < 1) { 79 fprintf(stderr, "-p: missing tcpcb address\n"); 80 exit(1); 81 } 82 if (npcbs >= TCP_NDEBUG) { 83 fprintf(stderr, "-p: too many pcb's specified\n"); 84 exit(1); 85 } 86 sscanf(*argv, "%x", &tcp_pcbs[npcbs++]); 87 argc--, argv++; 88 goto again; 89 } 90 if (argc > 0) { 91 system = *argv; 92 argc--, argv++; 93 mask++; 94 } 95 if (argc > 0) { 96 core = *argv; 97 argc--, argv++; 98 mask++; 99 } 100 (void) nlist(system, nl); 101 if (nl[0].n_value == 0) { 102 fprintf(stderr, "trpt: %s: no namelist\n", system); 103 exit(1); 104 } 105 (void) close(0); 106 if (open(core, 0) < 0) { 107 fprintf(stderr, "trpt: "); perror(core); 108 exit(2); 109 } 110 if (mask) { 111 nl[0].n_value &= 0x7fffffff; 112 nl[1].n_value &= 0x7fffffff; 113 } 114 (void) lseek(0, nl[1].n_value, 0); 115 if (read(0, &tcp_debx, sizeof (tcp_debx)) != sizeof (tcp_debx)) { 116 fprintf(stderr, "trpt: "); perror("tcp_debx"); 117 exit(3); 118 } 119 (void) lseek(0, nl[0].n_value, 0); 120 if (read(0, tcp_debug, sizeof (tcp_debug)) != sizeof (tcp_debug)) { 121 fprintf(stderr, "trpt: "); perror("tcp_debug"); 122 exit(3); 123 } 124 /* 125 * If no control blocks have been specified, figure 126 * out how many distinct one we have and summarize 127 * them in tcp_pcbs for sorting the trace records 128 * below. 129 */ 130 if (npcbs == 0) { 131 for (i = 0; i < TCP_NDEBUG; i++) { 132 register int j; 133 register struct tcp_debug *td = &tcp_debug[i]; 134 135 if (td->td_tcb == 0) 136 continue; 137 for (j = 0; j < npcbs; j++) 138 if (tcp_pcbs[j] == td->td_tcb) 139 break; 140 if (j >= npcbs) 141 tcp_pcbs[npcbs++] = td->td_tcb; 142 } 143 } 144 qsort(tcp_pcbs, npcbs, sizeof (caddr_t), numeric); 145 if (jflag) { 146 char *cp = ""; 147 148 for (i = 0; i < npcbs; i++) { 149 printf("%s%x", cp, tcp_pcbs[i]); 150 cp = ", "; 151 } 152 if (*cp) 153 putchar('\n'); 154 exit(0); 155 } 156 for (i = 0; i < npcbs; i++) { 157 printf("\n%x:\n", tcp_pcbs[i]); 158 dotrace(tcp_pcbs[i]); 159 } 160 exit(0); 161 } 162 163 dotrace(tcpcb) 164 register caddr_t tcpcb; 165 { 166 register int i; 167 register struct tcp_debug *td; 168 169 for (i = tcp_debx % TCP_NDEBUG; i < TCP_NDEBUG; i++) { 170 td = &tcp_debug[i]; 171 if (tcpcb && td->td_tcb != tcpcb) 172 continue; 173 ntime = ntohl(td->td_time); 174 tcp_trace(td->td_act, td->td_ostate, td->td_tcb, &td->td_cb, 175 &td->td_ti, td->td_req); 176 } 177 for (i = 0; i < tcp_debx % TCP_NDEBUG; i++) { 178 td = &tcp_debug[i]; 179 if (tcpcb && td->td_tcb != tcpcb) 180 continue; 181 ntime = ntohl(td->td_time); 182 tcp_trace(td->td_act, td->td_ostate, td->td_tcb, &td->td_cb, 183 &td->td_ti, td->td_req); 184 } 185 } 186 187 /* 188 * Tcp debug routines 189 */ 190 tcp_trace(act, ostate, atp, tp, ti, req) 191 short act, ostate; 192 struct tcpcb *atp, *tp; 193 struct tcpiphdr *ti; 194 int req; 195 { 196 tcp_seq seq, ack; 197 int len, flags, win, timer; 198 char *cp; 199 200 ptime(ntime); 201 printf("%s:%s ", tcpstates[ostate], tanames[act]); 202 switch (act) { 203 204 case TA_INPUT: 205 case TA_OUTPUT: 206 case TA_DROP: 207 if (aflag) { 208 printf("(src=%s,%d, ", inet_ntoa(ti->ti_src), 209 ntohs(ti->ti_sport)); 210 printf("dst=%s,%d)", inet_ntoa(ti->ti_dst), 211 ntohs(ti->ti_dport)); 212 } 213 seq = ti->ti_seq; 214 ack = ti->ti_ack; 215 len = ti->ti_len; 216 win = ti->ti_win; 217 if (act == TA_OUTPUT) { 218 seq = ntohl(seq); 219 ack = ntohl(ack); 220 len = ntohs(len); 221 win = ntohs(win); 222 } 223 if (act == TA_OUTPUT) 224 len -= sizeof (struct tcphdr); 225 if (len) 226 printf("[%x..%x)", seq, seq+len); 227 else 228 printf("%x", seq); 229 printf("@%x", ack); 230 if (win) 231 printf("(win=%x)", win); 232 flags = ti->ti_flags; 233 if (flags) { 234 char *cp = "<"; 235 #define pf(f) { if (ti->ti_flags&TH_/**/f) { printf("%s%s", cp, "f"); cp = ","; } } 236 pf(SYN); pf(ACK); pf(FIN); pf(RST); pf(PUSH); pf(URG); 237 printf(">"); 238 } 239 break; 240 241 case TA_USER: 242 timer = req >> 8; 243 req &= 0xff; 244 printf("%s", prurequests[req]); 245 if (req == PRU_SLOWTIMO || req == PRU_FASTTIMO) 246 printf("<%s>", tcptimers[timer]); 247 break; 248 } 249 printf(" -> %s", tcpstates[tp->t_state]); 250 /* print out internal state of tp !?! */ 251 printf("\n"); 252 if (sflag) { 253 printf("\trcv_nxt %x rcv_wnd %x snd_una %x snd_nxt %x snd_max %x\n", 254 tp->rcv_nxt, tp->rcv_wnd, tp->snd_una, tp->snd_nxt, 255 tp->snd_max); 256 printf("\tsnd_wl1 %x snd_wl2 %x snd_wnd %x\n", tp->snd_wl1, 257 tp->snd_wl2, tp->snd_wnd); 258 } 259 /* print out timers? */ 260 if (tflag) { 261 char *cp = "\t"; 262 register int i; 263 264 for (i = 0; i < TCPT_NTIMERS; i++) { 265 if (tp->t_timer[i] == 0) 266 continue; 267 printf("%s%s=%d", cp, tcptimers[i], tp->t_timer[i]); 268 if (i == TCPT_REXMT) 269 printf(" (t_rxtshft=%d)", tp->t_rxtshift); 270 cp = ", "; 271 } 272 if (*cp != '\t') 273 putchar('\n'); 274 } 275 } 276 277 ptime(ms) 278 int ms; 279 { 280 281 printf("%03d ", (ms/10) % 1000); 282 } 283 284 numeric(c1, c2) 285 caddr_t *c1, *c2; 286 { 287 288 return (*c1 - *c2); 289 } 290