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