1: /* 2: * Copyright (c) 1985 Regents of the University of California. 3: * All rights reserved. The Berkeley software License Agreement 4: * specifies the terms and conditions for redistribution. 5: */ 6: 7: #ifndef lint 8: char copyright[] = 9: "@(#) Copyright (c) 1980 Regents of the University of California.\n\ 10: All rights reserved.\n"; 11: #endif not lint 12: 13: #ifndef lint 14: static char sccsid[] = "@(#)trsp.c 6.1 (Berkeley) 10/8/85"; 15: #endif not lint 16: 17: #include <sys/param.h> 18: #include <sys/socket.h> 19: #include <sys/socketvar.h> 20: #define PRUREQUESTS 21: #include <sys/protosw.h> 22: 23: #include <net/route.h> 24: #include <net/if.h> 25: 26: #include <netinet/in.h> 27: #define TCPSTATES 28: #include <netinet/tcp_fsm.h> 29: #define TCPTIMERS 30: #include <netinet/tcp_timer.h> 31: 32: #include <netns/ns.h> 33: #include <netns/ns_pcb.h> 34: #include <netns/idp.h> 35: #include <netns/idp_var.h> 36: #include <netns/sp.h> 37: #include <netns/spidp.h> 38: #include <netns/spp_var.h> 39: #define SANAMES 40: #include <netns/spp_debug.h> 41: 42: #include <stdio.h> 43: #include <errno.h> 44: #include <nlist.h> 45: 46: unsigned long ntime; 47: int sflag; 48: int tflag; 49: int jflag; 50: int aflag; 51: int zflag; 52: int numeric(); 53: struct nlist nl[] = { 54: { "_spp_debug" }, 55: { "_spp_debx" }, 56: 0 57: }; 58: struct spp_debug spp_debug[SPP_NDEBUG]; 59: caddr_t spp_pcbs[SPP_NDEBUG]; 60: int spp_debx; 61: 62: main(argc, argv) 63: int argc; 64: char **argv; 65: { 66: int i, mask = 0, npcbs = 0; 67: char *system = "/vmunix", *core = "/dev/kmem"; 68: 69: argc--, argv++; 70: again: 71: if (argc > 0 && !strcmp(*argv, "-a")) { 72: aflag++, argc--, argv++; 73: goto again; 74: } 75: if (argc > 0 && !strcmp(*argv, "-z")) { 76: zflag++, argc--, argv++; 77: goto again; 78: } 79: if (argc > 0 && !strcmp(*argv, "-s")) { 80: sflag++, argc--, argv++; 81: goto again; 82: } 83: if (argc > 0 && !strcmp(*argv, "-t")) { 84: tflag++, argc--, argv++; 85: goto again; 86: } 87: if (argc > 0 && !strcmp(*argv, "-j")) { 88: jflag++, argc--, argv++; 89: goto again; 90: } 91: if (argc > 0 && !strcmp(*argv, "-p")) { 92: argc--, argv++; 93: if (argc < 1) { 94: fprintf(stderr, "-p: missing sppcb address\n"); 95: exit(1); 96: } 97: if (npcbs >= SPP_NDEBUG) { 98: fprintf(stderr, "-p: too many pcb's specified\n"); 99: exit(1); 100: } 101: sscanf(*argv, "%x", &spp_pcbs[npcbs++]); 102: argc--, argv++; 103: goto again; 104: } 105: if (argc > 0) { 106: system = *argv; 107: argc--, argv++; 108: mask++; 109: } 110: if (argc > 0) { 111: core = *argv; 112: argc--, argv++; 113: mask++; 114: } 115: (void) nlist(system, nl); 116: if (nl[0].n_value == 0) { 117: fprintf(stderr, "trsp: %s: no namelist\n", system); 118: exit(1); 119: } 120: (void) close(0); 121: if (open(core, 0) < 0) { 122: fprintf(stderr, "trsp: "); perror(core); 123: exit(2); 124: } 125: if (mask) { 126: nl[0].n_value &= 0x7fffffff; 127: nl[1].n_value &= 0x7fffffff; 128: } 129: (void) lseek(0, nl[1].n_value, 0); 130: if (read(0, &spp_debx, sizeof (spp_debx)) != sizeof (spp_debx)) { 131: fprintf(stderr, "trsp: "); perror("spp_debx"); 132: exit(3); 133: } 134: printf("spp_debx=%d\n", spp_debx); 135: (void) lseek(0, nl[0].n_value, 0); 136: if (read(0, spp_debug, sizeof (spp_debug)) != sizeof (spp_debug)) { 137: fprintf(stderr, "trsp: "); perror("spp_debug"); 138: exit(3); 139: } 140: /* 141: * Here, we just want to clear out the old trace data and start over. 142: */ 143: if (zflag) { 144: char *cp = (char *) spp_debug, 145: *cplim = cp + sizeof(spp_debug); 146: (void) close(0); 147: if (open(core, 2) < 0) { 148: fprintf(stderr, "trsp: "); perror(core); 149: exit(2); 150: } 151: while(cp < cplim) *cp++ = 0; 152: (void) lseek(0, nl[0].n_value, 0); 153: if (write(0, spp_debug, sizeof (spp_debug)) != sizeof (spp_debug)) { 154: fprintf(stderr, "trsp: "); perror("spp_debug"); 155: exit(3); 156: } 157: (void) lseek(0, nl[1].n_value, 0); 158: spp_debx = 0; 159: if (write(0, &spp_debx, sizeof (spp_debx)) != sizeof (spp_debx)) { 160: fprintf(stderr, "trsp: "); perror("spp_debx"); 161: exit(3); 162: } 163: exit(0); 164: } 165: /* 166: * If no control blocks have been specified, figure 167: * out how many distinct one we have and summarize 168: * them in spp_pcbs for sorting the trace records 169: * below. 170: */ 171: if (npcbs == 0) { 172: for (i = 0; i < SPP_NDEBUG; i++) { 173: register int j; 174: register struct spp_debug *sd = &spp_debug[i]; 175: 176: if (sd->sd_cb == 0) 177: continue; 178: for (j = 0; j < npcbs; j++) 179: if (spp_pcbs[j] == sd->sd_cb) 180: break; 181: if (j >= npcbs) 182: spp_pcbs[npcbs++] = sd->sd_cb; 183: } 184: } 185: qsort(spp_pcbs, npcbs, sizeof (caddr_t), numeric); 186: if (jflag) { 187: char *cp = ""; 188: 189: for (i = 0; i < npcbs; i++) { 190: printf("%s%x", cp, spp_pcbs[i]); 191: cp = ", "; 192: } 193: if (*cp) 194: putchar('\n'); 195: exit(0); 196: } 197: for (i = 0; i < npcbs; i++) { 198: printf("\n%x:\n", spp_pcbs[i]); 199: dotrace(spp_pcbs[i]); 200: } 201: exit(0); 202: } 203: 204: dotrace(sppcb) 205: register caddr_t sppcb; 206: { 207: register int i; 208: register struct spp_debug *sd; 209: 210: for (i = spp_debx % SPP_NDEBUG; i < SPP_NDEBUG; i++) { 211: sd = &spp_debug[i]; 212: if (sppcb && sd->sd_cb != sppcb) 213: continue; 214: ntime = ntohl(sd->sd_time); 215: spp_trace(sd->sd_act, sd->sd_ostate, sd->sd_cb, &sd->sd_sp, 216: &sd->sd_si, sd->sd_req); 217: } 218: for (i = 0; i < spp_debx % SPP_NDEBUG; i++) { 219: sd = &spp_debug[i]; 220: if (sppcb && sd->sd_cb != sppcb) 221: continue; 222: ntime = ntohl(sd->sd_time); 223: spp_trace(sd->sd_act, sd->sd_ostate, sd->sd_cb, &sd->sd_sp, 224: &sd->sd_si, sd->sd_req); 225: } 226: } 227: 228: ptime(ms) 229: int ms; 230: { 231: 232: printf("%03d ", (ms/10) % 1000); 233: } 234: 235: numeric(c1, c2) 236: caddr_t *c1, *c2; 237: { 238: 239: return (*c1 - *c2); 240: } 241: 242: spp_trace(act, ostate, asp, sp, si, req) 243: short act, ostate; 244: struct sppcb *asp, *sp; 245: struct spidp *si; 246: int req; 247: { 248: u_short seq, ack, len, alo; 249: int flags, timer; 250: char *cp; 251: 252: if(ostate >= TCP_NSTATES) ostate = 0; 253: if(act > SA_DROP) act = SA_DROP; 254: printf("\n"); 255: ptime(ntime); 256: printf("%s:%s", tcpstates[ostate], sanames[act]); 257: 258: if (si != 0) { 259: seq = si->si_seq; 260: ack = si->si_ack; 261: alo = si->si_alo; 262: len = si->si_len; 263: switch (act) { 264: case SA_RESPOND: 265: case SA_OUTPUT: 266: seq = ntohs(seq); 267: ack = ntohs(ack); 268: alo = ntohs(alo); 269: len = ntohs(len); 270: case SA_INPUT: 271: case SA_DROP: 272: if (aflag) { 273: printf("\n\tsna="); 274: ns_printhost(&si->si_sna); 275: printf("\tdna="); 276: ns_printhost(&si->si_dna); 277: } 278: printf("\n\t"); 279: #define p1(f) { printf("%s = %x, ", "f", f); } 280: p1(seq); p1(ack); p1(alo); p1(len); 281: flags = si->si_cc; 282: printf("flags=%x", flags); 283: if (flags) { 284: char *cp = "<"; 285: #define pf(f) { if (flags&SP_/**/f) { printf("%s%s", cp, "f"); cp = ","; } } 286: pf(SP); pf(SA); pf(OB); pf(EM); 287: printf(">"); 288: } 289: printf(", "); 290: #define p2(f) { printf("%s = %x, ", "f", si->si_/**/f); } 291: p2(sid);p2(did);p2(dt); 292: printf("\n\tsna="); 293: ns_printhost(&si->si_sna); 294: printf("\tdna="); 295: ns_printhost(&si->si_dna); 296: } 297: } 298: if(act == SA_USER) { 299: printf("\treq=%s", prurequests[req&0xff]); 300: if ((req & 0xff) == PRU_SLOWTIMO) 301: printf("<%s>", tcptimers[req>>8]); 302: } 303: printf(" -> %s", tcpstates[sp->s_state]); 304: 305: /* print out internal state of sp !?! */ 306: printf("\n"); 307: if (sp == 0) 308: return; 309: #define p3(f) { printf("%s = %x, ", "f", sp->s_/**/f); } 310: if(sflag) { 311: printf("\t"); p3(rack); p3(ralo); p3(snt); p3(flags); 312: #undef pf 313: #define pf(f) { if (flags&SF_/**/f) { printf("%s%s", cp, "f"); cp = ","; } } 314: flags = sp->s_flags; 315: if (flags || sp->s_oobflags) { 316: char *cp = "<"; 317: pf(AK); pf(DELACK); pf(HI); pf(HO); 318: flags = sp->s_oobflags; 319: pf(SOOB); pf(IOOB); 320: printf(">"); 321: } 322: 323: } 324: /* print out timers? */ 325: if (tflag) { 326: char *cp = "\t"; 327: register int i; 328: 329: printf("\n\tTIMERS: "); 330: p3(idle); p3(force); p3(rtseq); 331: for (i = 0; i < TCPT_NTIMERS; i++) { 332: if (sp->s_timer[i] == 0) 333: continue; 334: printf("%s%s=%d", cp, tcptimers[i], sp->s_timer[i]); 335: if (i == TCPT_REXMT) 336: printf(" (s_rxtshft=%d)", sp->s_rxtshift); 337: cp = ", "; 338: } 339: if (*cp != '\t') 340: putchar('\n'); 341: } 342: } 343: 344: ns_printhost(p) 345: register struct ns_addr *p; 346: { 347: 348: printf("<net:%x%x,host:%4.4x%4.4x%4.4x,port:%x>", 349: p->x_net.s_net[0], 350: p->x_net.s_net[1], 351: p->x_host.s_host[0], 352: p->x_host.s_host[1], 353: p->x_host.s_host[2], 354: p->x_port); 355: 356: }