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