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