|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1983, 1988 Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms are permitted ! 6: * provided that the above copyright notice and this paragraph are ! 7: * duplicated in all such forms and that any documentation, ! 8: * advertising materials, and other materials related to such ! 9: * distribution and use acknowledge that the software was developed ! 10: * by the University of California, Berkeley. The name of the ! 11: * University may not be used to endorse or promote products derived ! 12: * from this software without specific prior written permission. ! 13: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ! 14: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ! 15: * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 16: */ ! 17: ! 18: #ifndef lint ! 19: char copyright[] = ! 20: "@(#) Copyright (c) 1983, 1988 Regents of the University of California.\n\ ! 21: All rights reserved.\n"; ! 22: #endif /* not lint */ ! 23: ! 24: #ifndef lint ! 25: static char sccsid[] = "@(#)trpt.c 5.5 (Berkeley) 7/1/88"; ! 26: #endif /* not lint */ ! 27: ! 28: #include <machine/pte.h> ! 29: ! 30: #include <sys/param.h> ! 31: #include <sys/vmmac.h> ! 32: #include <sys/socket.h> ! 33: #include <sys/socketvar.h> ! 34: #define PRUREQUESTS ! 35: #include <sys/protosw.h> ! 36: #include <sys/file.h> ! 37: ! 38: #include <net/route.h> ! 39: #include <net/if.h> ! 40: ! 41: #include <netinet/in.h> ! 42: #include <netinet/in_pcb.h> ! 43: #include <netinet/in_systm.h> ! 44: #include <netinet/ip.h> ! 45: #include <netinet/ip_var.h> ! 46: #include <netinet/tcp.h> ! 47: #define TCPSTATES ! 48: #include <netinet/tcp_fsm.h> ! 49: #include <netinet/tcp_seq.h> ! 50: #define TCPTIMERS ! 51: #include <netinet/tcp_timer.h> ! 52: #include <netinet/tcp_var.h> ! 53: #include <netinet/tcpip.h> ! 54: #define TANAMES ! 55: #include <netinet/tcp_debug.h> ! 56: ! 57: #include <arpa/inet.h> ! 58: ! 59: #include <stdio.h> ! 60: #include <errno.h> ! 61: #include <nlist.h> ! 62: ! 63: struct nlist nl[] = { ! 64: #define N_TCP_DEBUG 0 ! 65: { "_tcp_debug" }, ! 66: #define N_TCP_DEBX 1 ! 67: { "_tcp_debx" }, ! 68: #define N_SYSMAP 2 ! 69: { "_Sysmap" }, ! 70: #define N_SYSSIZE 3 ! 71: { "_Syssize" }, ! 72: { "" }, ! 73: }; ! 74: ! 75: static struct pte *Sysmap; ! 76: static struct tcp_debug tcp_debug[TCP_NDEBUG]; ! 77: static caddr_t tcp_pcbs[TCP_NDEBUG]; ! 78: static n_time ntime; ! 79: static int aflag, kflag, memf, follow, sflag, tcp_debx, tflag; ! 80: ! 81: main(argc, argv) ! 82: int argc; ! 83: char **argv; ! 84: { ! 85: extern char *optarg; ! 86: extern int optind; ! 87: int ch, i, jflag, npcbs, numeric(); ! 88: char *system, *core, *malloc(); ! 89: off_t lseek(); ! 90: ! 91: jflag = npcbs = 0; ! 92: while ((ch = getopt(argc, argv, "afjp:st")) != EOF) ! 93: switch((char)ch) { ! 94: case 'a': ! 95: ++aflag; ! 96: break; ! 97: case 'f': ! 98: ++follow; ! 99: setlinebuf(stdout); ! 100: break; ! 101: case 'j': ! 102: ++jflag; ! 103: break; ! 104: case 'p': ! 105: if (npcbs >= TCP_NDEBUG) { ! 106: fputs("trpt: too many pcb's specified\n", ! 107: stderr); ! 108: exit(1); ! 109: } ! 110: (void)sscanf(optarg, "%x", (int *)&tcp_pcbs[npcbs++]); ! 111: break; ! 112: case 's': ! 113: ++sflag; ! 114: break; ! 115: case 't': ! 116: ++tflag; ! 117: break; ! 118: case '?': ! 119: default: ! 120: fputs("usage: trpt [-afjst] [-p hex-address] [system [core]]\n", stderr); ! 121: exit(1); ! 122: } ! 123: argc -= optind; ! 124: argv += optind; ! 125: ! 126: core = "/dev/kmem"; ! 127: if (argc > 0) { ! 128: system = *argv; ! 129: argc--, argv++; ! 130: if (argc > 0) { ! 131: core = *argv; ! 132: argc--, argv++; ! 133: ++kflag; ! 134: } ! 135: } ! 136: else ! 137: system = "/vmunix"; ! 138: ! 139: if (nlist(system, nl) < 0 || !nl[0].n_value) { ! 140: fprintf(stderr, "trpt: %s: no namelist\n", system); ! 141: exit(1); ! 142: } ! 143: if ((memf = open(core, O_RDONLY)) < 0) { ! 144: perror(core); ! 145: exit(2); ! 146: } ! 147: if (kflag) { ! 148: off_t off; ! 149: ! 150: Sysmap = (struct pte *) ! 151: malloc((u_int)(nl[N_SYSSIZE].n_value * sizeof(struct pte))); ! 152: if (!Sysmap) { ! 153: fputs("arp: can't get memory for Sysmap.\n", stderr); ! 154: exit(1); ! 155: } ! 156: off = nl[N_SYSMAP].n_value & ~KERNBASE; ! 157: (void)lseek(memf, off, L_SET); ! 158: (void)read(memf, (char *)Sysmap, ! 159: (int)(nl[N_SYSSIZE].n_value * sizeof(struct pte))); ! 160: } ! 161: (void)klseek(memf, (off_t)nl[N_TCP_DEBX].n_value, L_SET); ! 162: if (read(memf, (char *)&tcp_debx, sizeof(tcp_debx)) != ! 163: sizeof(tcp_debx)) { ! 164: perror("trpt: tcp_debx"); ! 165: exit(3); ! 166: } ! 167: (void)klseek(memf, (off_t)nl[N_TCP_DEBUG].n_value, L_SET); ! 168: if (read(memf, (char *)tcp_debug, sizeof(tcp_debug)) != ! 169: sizeof(tcp_debug)) { ! 170: perror("trpt: tcp_debug"); ! 171: exit(3); ! 172: } ! 173: /* ! 174: * If no control blocks have been specified, figure ! 175: * out how many distinct one we have and summarize ! 176: * them in tcp_pcbs for sorting the trace records ! 177: * below. ! 178: */ ! 179: if (!npcbs) { ! 180: for (i = 0; i < TCP_NDEBUG; i++) { ! 181: register struct tcp_debug *td = &tcp_debug[i]; ! 182: register int j; ! 183: ! 184: if (td->td_tcb == 0) ! 185: continue; ! 186: for (j = 0; j < npcbs; j++) ! 187: if (tcp_pcbs[j] == td->td_tcb) ! 188: break; ! 189: if (j >= npcbs) ! 190: tcp_pcbs[npcbs++] = td->td_tcb; ! 191: } ! 192: if (!npcbs) ! 193: exit(0); ! 194: } ! 195: qsort(tcp_pcbs, npcbs, sizeof(caddr_t), numeric); ! 196: if (jflag) { ! 197: for (i = 0;;) { ! 198: printf("%x", (int)tcp_pcbs[i]); ! 199: if (++i == npcbs) ! 200: break; ! 201: fputs(", ", stdout); ! 202: } ! 203: putchar('\n'); ! 204: } ! 205: else for (i = 0; i < npcbs; i++) { ! 206: printf("\n%x:\n", (int)tcp_pcbs[i]); ! 207: dotrace(tcp_pcbs[i]); ! 208: } ! 209: exit(0); ! 210: } ! 211: ! 212: dotrace(tcpcb) ! 213: register caddr_t tcpcb; ! 214: { ! 215: register struct tcp_debug *td; ! 216: register int i; ! 217: int prev_debx = tcp_debx; ! 218: ! 219: again: if (--tcp_debx < 0) ! 220: tcp_debx = TCP_NDEBUG - 1; ! 221: for (i = prev_debx % TCP_NDEBUG; i < TCP_NDEBUG; i++) { ! 222: td = &tcp_debug[i]; ! 223: if (tcpcb && td->td_tcb != tcpcb) ! 224: continue; ! 225: ntime = ntohl(td->td_time); ! 226: tcp_trace(td->td_act, td->td_ostate, td->td_tcb, &td->td_cb, ! 227: &td->td_ti, td->td_req); ! 228: if (i == tcp_debx) ! 229: goto done; ! 230: } ! 231: for (i = 0; i <= tcp_debx % TCP_NDEBUG; i++) { ! 232: td = &tcp_debug[i]; ! 233: if (tcpcb && td->td_tcb != tcpcb) ! 234: continue; ! 235: ntime = ntohl(td->td_time); ! 236: tcp_trace(td->td_act, td->td_ostate, td->td_tcb, &td->td_cb, ! 237: &td->td_ti, td->td_req); ! 238: } ! 239: done: if (follow) { ! 240: prev_debx = tcp_debx + 1; ! 241: if (prev_debx >= TCP_NDEBUG) ! 242: prev_debx = 0; ! 243: do { ! 244: sleep(1); ! 245: (void)klseek(memf, (off_t)nl[N_TCP_DEBX].n_value, L_SET); ! 246: if (read(memf, (char *)&tcp_debx, sizeof(tcp_debx)) != ! 247: sizeof(tcp_debx)) { ! 248: perror("trpt: tcp_debx"); ! 249: exit(3); ! 250: } ! 251: } while (tcp_debx == prev_debx); ! 252: (void)klseek(memf, (off_t)nl[N_TCP_DEBUG].n_value, L_SET); ! 253: if (read(memf, (char *)tcp_debug, sizeof(tcp_debug)) != ! 254: sizeof(tcp_debug)) { ! 255: perror("trpt: tcp_debug"); ! 256: exit(3); ! 257: } ! 258: goto again; ! 259: } ! 260: } ! 261: ! 262: /* ! 263: * Tcp debug routines ! 264: */ ! 265: /*ARGSUSED*/ ! 266: tcp_trace(act, ostate, atp, tp, ti, req) ! 267: short act, ostate; ! 268: struct tcpcb *atp, *tp; ! 269: struct tcpiphdr *ti; ! 270: int req; ! 271: { ! 272: tcp_seq seq, ack; ! 273: int flags, len, win, timer; ! 274: ! 275: printf("%03ld %s:%s ",(ntime/10) % 1000, tcpstates[ostate], ! 276: tanames[act]); ! 277: switch (act) { ! 278: case TA_INPUT: ! 279: case TA_OUTPUT: ! 280: case TA_DROP: ! 281: if (aflag) ! 282: printf("(src=%s,%u, dst=%s,%u)", inet_ntoa(ti->ti_src), ! 283: ntohs(ti->ti_sport), inet_ntoa(ti->ti_dst), ! 284: ntohs(ti->ti_dport)); ! 285: seq = ti->ti_seq; ! 286: ack = ti->ti_ack; ! 287: len = ti->ti_len; ! 288: win = ti->ti_win; ! 289: if (act == TA_OUTPUT) { ! 290: seq = ntohl(seq); ! 291: ack = ntohl(ack); ! 292: len = ntohs(len); ! 293: win = ntohs(win); ! 294: } ! 295: if (act == TA_OUTPUT) ! 296: len -= sizeof(struct tcphdr); ! 297: if (len) ! 298: printf("[%lx..%lx)", seq, seq + len); ! 299: else ! 300: printf("%lx", seq); ! 301: printf("@%lx", ack); ! 302: if (win) ! 303: printf("(win=%x)", win); ! 304: flags = ti->ti_flags; ! 305: if (flags) { ! 306: register char *cp = "<"; ! 307: #define pf(flag) { \ ! 308: if (ti->ti_flags&flag) \ ! 309: printf("%s%s", cp, "f"); \ ! 310: cp = ","; \ ! 311: } ! 312: pf(TH_SYN); ! 313: pf(TH_ACK); ! 314: pf(TH_FIN); ! 315: pf(TH_RST); ! 316: pf(TH_PUSH); ! 317: pf(TH_URG); ! 318: printf(">"); ! 319: } ! 320: break; ! 321: case TA_USER: ! 322: timer = req >> 8; ! 323: req &= 0xff; ! 324: printf("%s", prurequests[req]); ! 325: if (req == PRU_SLOWTIMO || req == PRU_FASTTIMO) ! 326: printf("<%s>", tcptimers[timer]); ! 327: break; ! 328: } ! 329: printf(" -> %s", tcpstates[tp->t_state]); ! 330: /* print out internal state of tp !?! */ ! 331: printf("\n"); ! 332: if (sflag) { ! 333: printf("\trcv_nxt %lx rcv_wnd %x snd_una %lx snd_nxt %lx snd_max %lx\n", ! 334: tp->rcv_nxt, tp->rcv_wnd, tp->snd_una, tp->snd_nxt, ! 335: tp->snd_max); ! 336: printf("\tsnd_wl1 %lx snd_wl2 %lx snd_wnd %x\n", tp->snd_wl1, ! 337: tp->snd_wl2, tp->snd_wnd); ! 338: } ! 339: /* print out timers? */ ! 340: if (tflag) { ! 341: register char *cp = "\t"; ! 342: register int i; ! 343: ! 344: for (i = 0; i < TCPT_NTIMERS; i++) { ! 345: if (tp->t_timer[i] == 0) ! 346: continue; ! 347: printf("%s%s=%d", cp, tcptimers[i], tp->t_timer[i]); ! 348: if (i == TCPT_REXMT) ! 349: printf(" (t_rxtshft=%d)", tp->t_rxtshift); ! 350: cp = ", "; ! 351: } ! 352: if (*cp != '\t') ! 353: putchar('\n'); ! 354: } ! 355: } ! 356: ! 357: numeric(c1, c2) ! 358: caddr_t *c1, *c2; ! 359: { ! 360: return(*c1 - *c2); ! 361: } ! 362: ! 363: klseek(fd, base, off) ! 364: int fd, off; ! 365: off_t base; ! 366: { ! 367: off_t lseek(); ! 368: ! 369: if (kflag) { /* get kernel pte */ ! 370: base &= ~KERNBASE; ! 371: base = ctob(Sysmap[btop(base)].pg_pfnum) + (base & PGOFSET); ! 372: } ! 373: (void)lseek(fd, base, off); ! 374: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.